Changeset 1137344
- Timestamp:
- 04/17/2015 04:24:10 PM (11 years ago)
- Location:
- expresscurate/trunk
- Files:
-
- 33 edited
-
ExpressCurate.php (modified) (1 diff)
-
ExpressCurate_API.php (modified) (1 diff)
-
ExpressCurate_Actions.php (modified) (8 diffs)
-
ExpressCurate_AjaxExportAPI.php (modified) (3 diffs)
-
ExpressCurate_ContentManager.php (modified) (2 diffs)
-
ExpressCurate_CronManager.php (modified) (1 diff)
-
ExpressCurate_Date.php (modified) (1 diff)
-
ExpressCurate_Email.php (modified) (2 diffs)
-
ExpressCurate_FeedManager.php (modified) (17 diffs)
-
ExpressCurate_GoogleAuth.php (modified) (1 diff)
-
ExpressCurate_HtmlParser.php (modified) (3 diffs)
-
ExpressCurate_Keywords.php (modified) (1 diff)
-
ExpressCurate_Sitemap.php (modified) (1 diff)
-
ExpressCurate_Tags.php (modified) (2 diffs)
-
autoload.php (modified) (1 diff)
-
css/dialog-style-3.9.css (modified) (8 diffs)
-
css/expresscurate.css (modified) (16 diffs)
-
js/Dialog.js (modified) (17 diffs)
-
js/Utils.js (modified) (2 diffs)
-
js/feed/contentFeed.js (modified) (2 diffs)
-
js/keywords/SEOControlCenter.js (modified) (3 diffs)
-
js/sourceCollection.js (modified) (1 diff)
-
readme.txt (modified) (3 diffs)
-
templates/advanced_seo_widget.php (modified) (1 diff)
-
templates/bookmarks.php (modified) (2 diffs)
-
templates/dashboard.php (modified) (1 diff)
-
templates/dialog.php (modified) (4 diffs)
-
templates/feed_dashboard.php (modified) (3 diffs)
-
templates/feed_list.php (modified) (7 diffs)
-
templates/keywords.php (modified) (1 diff)
-
templates/news.php (modified) (1 diff)
-
templates/settings.php (modified) (4 diffs)
-
templates/websites.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
expresscurate/trunk/ExpressCurate.php
r1129694 r1137344 5 5 Plugin URI: http://www.expresscurate.com/products 6 6 Description: ExpressCurate plugin is a content curation tool for WordPress. It enables you to create and publish high quality content within minutes. 7 Version: 2.0.1 07 Version: 2.0.11 8 8 Author: ExpressCurate 9 9 Author URI: http://www.expresscurate.com -
expresscurate/trunk/ExpressCurate_API.php
r1106118 r1137344 4 4 5 5 /* 6 * Returnes source urls of all posts if $post_id is not defined 7 * @param int $post_id 8 * @return array 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 9 10 */ 10 11 -
expresscurate/trunk/ExpressCurate_Actions.php
r1129694 r1137344 1 1 <?php 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 4 2 5 /* 3 6 Author: ExpressCurate … … 6 9 License URI: http://www.gnu.org/licenses/gpl.html 7 10 */ 8 require_once(sprintf("%s/autoload.php", dirname(__FILE__)));9 10 11 11 12 class ExpressCurate_Actions … … 75 76 add_action('manage_posts_custom_column', array(&$this, 'curated_column_display'), 10, 2); 76 77 add_filter('manage_edit-post_sortable_columns', array(&$this, 'curated_column_register_sortable')); 77 78 78 79 79 add_filter('request', array(&$this, 'curated_column_orderby')); … … 137 137 add_action('wp_ajax_expresscurate_save_sitemap_google_status', array(&$this->sitemap, 'saveSitemapGoogleStatus')); 138 138 139 140 139 add_action('wp_ajax_expresscurate_feed_add', array($this->feedManager, 'add_feed')); 141 140 add_action('wp_ajax_expresscurate_feed_delete', array($this->feedManager, 'delete_feed')); 141 add_action('wp_ajax_expresscurate_show_content_feed_items', array($this->feedManager, 'show_content_feed_items')); 142 142 add_action('wp_ajax_expresscurate_bookmarks_add', array($this->feedManager, 'add_bookmarks')); 143 143 add_action('wp_ajax_expresscurate_bookmark_set', array($this->feedManager, 'set_bookmark')); … … 200 200 register_setting('expresscurate-keywords-group', 'expresscurate_defined_tags'); 201 201 register_setting('expresscurate-group', 'expresscurate_curated_text'); 202 register_setting('expresscurate-group', 'expresscurate_curated_link_target'); 202 203 register_setting('expresscurate-group', 'expresscurate_featured'); 203 204 register_setting('expresscurate-group', 'expresscurate_seo'); … … 376 377 return; 377 378 $curated = get_post_meta($post_id, '_is_expresscurate', true); 378 if ($curated == 1) { 379 $curated = '<em>' . __('Yes', self::PLUGIN_FOLDER) . '</em>'; 380 } else { 381 $curated = '<em>' . __('No', self::PLUGIN_FOLDER) . '</em>'; 382 } 379 //$cloned = get_post_meta($post_id, '_expresscurate_advanced_seo_post_copy', true); 380 //if($cloned=='on'){ 381 // $curated = '<em>' . __('Cloned', self::PLUGIN_FOLDER) . '</em>'; 382 // }else{ 383 if ($curated == 1) { 384 $curated = '<em>' . __('Yes', self::PLUGIN_FOLDER) . '</em>'; 385 } else { 386 $curated = '<em>' . __('No', self::PLUGIN_FOLDER) . '</em>'; 387 } 388 // } 383 389 echo $curated; 384 390 } … … 697 703 $expresscurate_advanced_seo_nofollow = isset($_POST['expresscurate_advanced_seo_nofollow_value']) ? $_POST['expresscurate_advanced_seo_nofollow_value'] : 'on'; 698 704 $expresscurate_advanced_seo_noindex = isset($_POST['expresscurate_advanced_seo_noindex_value']) ? $_POST['expresscurate_advanced_seo_noindex_value'] : 'on'; 705 $expresscurate_advanced_seo_post_copy = isset($_POST['expresscurate_advanced_seo_post_copy_value']) ? $_POST['expresscurate_advanced_seo_post_copy_value'] : 'off'; 699 706 700 707 update_post_meta($post_id, '_expresscurate_advanced_seo_title', esc_attr($expresscurate_advanced_seo_title)); … … 702 709 update_post_meta($post_id, '_expresscurate_advanced_seo_nofollow', esc_attr($expresscurate_advanced_seo_nofollow)); 703 710 update_post_meta($post_id, '_expresscurate_advanced_seo_noindex', esc_attr($expresscurate_advanced_seo_noindex)); 711 update_post_meta($post_id, '_expresscurate_advanced_seo_post_copy', esc_attr($expresscurate_advanced_seo_post_copy)); 704 712 705 713 // social part -
expresscurate/trunk/ExpressCurate_AjaxExportAPI.php
r1129694 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 3 4 … … 37 38 $data["smart_publishing"] = get_option('expresscurate_publish', '') == 'on' ? get_option('expresscurate_manually_approve_smart', 'off') : 'off'; 38 39 $data["curated_from_prefix"] = get_option("expresscurate_curated_text", 'See full story on'); 40 $data["curated_link_target"] = get_option("expresscurate_curated_link_target", 'on'); 39 41 if (current_user_can('edit_posts')) { 40 42 $categories = get_categories(array("hide_empty" => 0)); … … 186 188 $domain = parse_url($data['url']); 187 189 $domain = $domain['host']; 188 $data['content'] .= '<div class="curated_from"><p>' . get_option('expresscurate_curated_text') . ' <a href = "' . $data['url'] . '">' . $domain . '</a><span class="expresscurated" data-curated-url="' . $data['url'] . '"> </span></p></div>';190 //$data['content'] .= '<div class="curated_from"><p>' . get_option('expresscurate_curated_text') . ' <a href = "' . $data['url'] . '">' . $domain . '</a><span class="expresscurated" data-curated-url="' . $data['url'] . '"> </span></p></div>'; 189 191 if (isset($data['terms'])) { 190 192 foreach ($data['terms'] as $i => $term) { -
expresscurate/trunk/ExpressCurate_ContentManager.php
r1129694 r1137344 1 1 <?php 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 2 4 3 5 /* … … 7 9 License URI: http://www.gnu.org/licenses/gpl.html 8 10 */ 9 require_once(sprintf("%s/autoload.php", dirname(__FILE__)));10 11 11 12 class ExpressCurate_ContentManager { -
expresscurate/trunk/ExpressCurate_CronManager.php
r1111122 r1137344 1 1 <?php 2 2 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 3 4 /* 5 Author: ExpressCurate 6 Author URI: http://www.expresscurate.com 7 License: GPLv3 or later 8 License URI: http://www.gnu.org/licenses/gpl.html 9 */ 3 10 4 11 class ExpressCurate_CronManager { -
expresscurate/trunk/ExpressCurate_Date.php
r1106118 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 4 5 /* 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 10 */ 11 3 12 /** 4 13 * Class responsible for date formatting -
expresscurate/trunk/ExpressCurate_Email.php
r1106118 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 4 5 /* 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 10 */ 3 11 4 12 class ExpressCurate_Email … … 17 25 $headers = 'Content-type: text/html; charset=utf-8' . "\r\n"; 18 26 foreach ($wpUsers as $user) { 27 // don't sent alerts to subscribers 28 if(in_array('subscriber', $user->roles)) { 29 continue; 30 } 19 31 @wp_mail($user->user_email, 'ExpressCurate Content Alert', $email, $headers); 20 32 } -
expresscurate/trunk/ExpressCurate_FeedManager.php
r1129694 r1137344 11 11 class ExpressCurate_FeedManager 12 12 { 13 13 const CONTENT_FEED_MAX_SIZE = 500; 14 14 15 15 private static $instance; … … 34 34 if(!ExpressCurate_HtmlParser::supportsDownload()){ 35 35 $result = array("status"=>"You should activate either curl extension or allow_url_fopen setting."); 36 } else{36 } else { 37 37 $url = isset($url) ? $url : $_REQUEST['url']; 38 38 $url = trim($url); … … 47 47 } 48 48 49 //$url = expresscurate_normalise_url($url, true); 50 $rssUrl = isset($rssUrl) ? $rssUrl : $this->getRssUrl($url); 51 52 if (!isset($curated_links_rss[$rssUrl])) { 49 $rssUrl = $this->getRssUrl($url); 50 51 if ($rssUrl === null) { 52 $result['status'] = 'No RSS feed found at this URL.'; 53 } else if (isset($curated_links_rss[$rssUrl])) { 54 $result['status'] = 'URL already exists.'; 55 } else { 53 56 if (filter_var($rssUrl, FILTER_VALIDATE_URL)) { 54 57 $result['status'] = 'success'; 58 59 // retrieve the feed title 60 $feedMeta = $this->getFeedMeta($rssUrl); 61 $link = $feedMeta['link']; 62 $link = empty($link) ? $rssUrl : $link; 63 64 // get the number of posts that are curated from this feed 55 65 $metas = $wpdb->get_results( 56 66 "SELECT post_id 57 FROM $wpdb->postmeta58 WHERE meta_key LIKE '%_expresscurate_link_%' AND meta_value LIKE '%" . $url. "%' GROUP BY post_id");59 60 61 $curated_links_rss[$ rssUrl]['feed_url'] = $result['feed_url'] = $rssUrl;62 $curated_links_rss[$ rssUrl]['post_count'] = $result['post_count'] = count($metas);63 // var_dump($curated_links_rss);die;64 $curated_links_rss = json_encode($curated_links_rss);65 update_option('expresscurate_links_rss', $curated_links_rss);66 } elseif ($rssUrl === null) {67 $result['status'] = 'No RSS feed found at this URL.';67 FROM $wpdb->postmeta 68 WHERE meta_key LIKE '%_expresscurate_link_%' AND meta_value LIKE '%" . $link . "%' GROUP BY post_id"); 69 70 // construct the rss data 71 $curated_links_rss[$link]['feed_url'] = $result['feed_url'] = $rssUrl; 72 $curated_links_rss[$link]['link'] = $result['link'] = $link; 73 $curated_links_rss[$link]['post_count'] = $result['post_count'] = count($metas); 74 $curated_links_rss[$link]['feed_title'] = $result['feed_title'] = $feedMeta['title']; 75 76 // save 77 update_option('expresscurate_links_rss', json_encode($curated_links_rss)); 68 78 } else { 69 79 $result['status'] = 'Invalid RSS URL.'; 70 80 } 71 } else {72 $result['status'] = 'URL already exists.';73 81 } 74 82 } else { … … 79 87 80 88 die; 89 } 90 91 private function getFeedMeta($feedURL) { 92 $loadURL = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=" . urlencode($feedURL); 93 $htmlparser = new ExpressCurate_HtmlParser($loadURL); 94 $res = $htmlparser->download(); 95 $result = json_decode($res, true); 96 97 if(isset($result['responseData']) && isset($result['responseData']['feed'])) { 98 $meta = array(); 99 $meta['title'] = $result['responseData']['feed']['title']; 100 $meta['feed'] = $result['responseData']['feed']['feedUrl']; 101 $meta['link'] = $result['responseData']['feed']['link']; 102 return $meta; 103 } else { 104 return null; 105 } 81 106 } 82 107 … … 96 121 } else { 97 122 unset($curated_links_rss[$data['url']]); 98 $curated_links_rss = json_encode($curated_links_rss); 99 update_option('expresscurate_links_rss', $curated_links_rss); 123 update_option('expresscurate_links_rss', json_encode($curated_links_rss)); 100 124 $result['status'] = 'success'; 101 125 } … … 127 151 if ($curated_links_rss) { 128 152 $curated_links_rss = json_decode($curated_links_rss, true); 153 154 $links = array(); 155 foreach($curated_links_rss as $link => $data) { 156 $url = $data['feed_url']; 157 $links[$url] = 1; 158 } 159 $curated_links_rss = $links; 129 160 } else { 130 161 $curated_links_rss = array(); … … 133 164 134 165 if ($top_sources_rss) { 135 $top_sources_rss = json_decode($top_sources_rss, true); 136 $date_after = strtotime($top_sources_rss['date']) . "&"; 166 // check if migrated 167 $migrated1 = (isset($top_sources_rss['migrated']) && $top_sources_rss['migrated']== 1); 168 // if not migrated, clean the data up, calculate stats from scratch 169 $top_sources_rss = $migrated1 ? json_decode($top_sources_rss, true) : array(); 170 $date_after = $migrated1 ? strtotime($top_sources_rss['date']) . "&" : ''; 137 171 } else { 138 172 $top_sources_rss = array(); 139 173 $top_sources_rss['links'] = array(); 140 174 } 175 $top_sources_rss['migrated'] = 1; 141 176 142 177 $curated_posts_query = new WP_Query("meta_key=_is_expresscurate&meta_value=1&posts_per_page=-1&" . $date_after . "order=DESC"); … … 151 186 if (preg_match('/_expresscurate_link_\d/', $key)) { 152 187 if ($meta_values[$key][0]) { 153 $normalised_url = expresscurate_normalise_url($meta_values[$key][0]); 154 $domain = parse_url($normalised_url); 155 if (preg_match('/(?P<subdomain>.<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain['host'], $regs)) { 156 $curated_links[$i]['link'] = expresscurate_normalise_url($regs['domain']); 157 } else { 158 $curated_links[$i]['link'] = $normalised_url; 188 // parse the host 189 $url = parse_url($meta_values[$key][0]); 190 $host = $url['host']; 191 192 // get only the main domain 193 preg_match('/([a-z0-9\-_]{1,63})\.([a-z]{2,6})$/i', $host, $regs); 194 $link = $regs[1] . '.' . $regs[2]; 195 196 // filter 197 if(empty($link) || $link == '.') { 198 continue; 159 199 } 200 201 // add 202 $curated_links[$i]['host'] = $host; 203 $curated_links[$i]['link'] = $link; 160 204 $curated_links[$i]['post_id'] = get_the_ID(); 205 $i++; 161 206 } 162 $i++;163 207 } 164 208 } … … 166 210 } 167 211 wp_reset_postdata(); 168 if(ExpressCurate_HtmlParser::supportsDownload()){ 212 213 $rssLinks = array(); 214 215 if(ExpressCurate_HtmlParser::supportsDownload()) { 169 216 foreach ($curated_links as $key => $top_link) { 170 $websiteUrl = $top_link['link']; 171 $rssUrl = $this->getRssUrl($websiteUrl); 217 $websiteHost = $top_link['host']; 218 $website = $top_link['link']; 219 220 if(isset($rssLinks[$websiteHost])) { 221 $rssUrl = $rssLinks[$websiteHost]; 222 } else { 223 $rssUrl = $this->getRssUrl($websiteHost); 224 $rssLinks[$websiteHost] = $rssUrl; 225 } 226 172 227 if ($rssUrl && isset($curated_links_rss[$rssUrl])) { 173 228 $feed_status = 'rssStatusYes'; … … 179 234 } 180 235 } 181 $top_sources_rss['links'][$websiteUrl] = array( 236 237 $top_sources_rss['links'][$website] = array( 182 238 'post_ids' => array($top_link['post_id']), 183 239 'feed_options' => array( … … 186 242 'type' => 'feed') 187 243 ); 188 $top_sources_rss['links'][$website Url]['post_ids'] = array_unique($top_sources_rss['links'][$websiteUrl]['post_ids']);189 $top_sources_rss['links'][$website Url]['post_count'] = count($top_sources_rss['links'][$websiteUrl]['post_ids']);244 $top_sources_rss['links'][$website]['post_ids'] = array_unique($top_sources_rss['links'][$website]['post_ids']); 245 $top_sources_rss['links'][$website]['post_count'] = count($top_sources_rss['links'][$website]['post_ids']); 190 246 } 191 247 … … 211 267 public function get_rss_list() 212 268 { 269 global $wpdb; 270 213 271 $curated_links_rss = get_option('expresscurate_links_rss', ''); 214 272 if ($curated_links_rss) { 215 273 $curated_links_rss = json_decode($curated_links_rss, true); 274 275 $save = false; 276 foreach($curated_links_rss as $rss => $data) { 277 if(isset($data['feed_title']) && strlen(trim($data['feed_title'])) > 0) { 278 continue; 279 } 280 281 // correct the url and get the meta data 282 $rssUrl = $this->getRssUrl($rss); 283 $feedMeta = $this->getFeedMeta($rssUrl); 284 $link = $feedMeta['link']; 285 $link = empty($link) ? $rssUrl : $link; 286 287 $data = array(); 288 $data['feed_title'] = $feedMeta['title']; 289 $data['feed_url'] = $rssUrl; 290 $data['link'] = $link; 291 292 // remove the old row and add the new one 293 unset($curated_links_rss[$rss]); 294 $curated_links_rss[$link] = $data; 295 296 // make sure to save in the end 297 $save = true; 298 } 299 300 // update the post count 301 foreach($curated_links_rss as $link => $data) { 302 // get the number of posts that are curated from this feed 303 $posts = $wpdb->get_results( 304 "SELECT post_id 305 FROM $wpdb->postmeta 306 WHERE meta_key LIKE '%_expresscurate_link_%' AND meta_value LIKE '%" . $link . "%' GROUP BY post_id"); 307 308 $curated_links_rss[$link]['post_count'] = count($posts); 309 } 310 311 // save 312 update_option('expresscurate_links_rss', json_encode($curated_links_rss)); 216 313 } else { 217 314 $curated_links_rss = array(); 218 315 } 316 317 unset($curated_links_rss['']); 219 318 return $curated_links_rss; 220 319 } … … 253 352 254 353 $lookup_url = "http://ajax.googleapis.com/ajax/services/feed/lookup?v=1.0&q=" . urlencode($url); 255 /*$options = array('http' => array('user_agent' => USER_AGENT,'request_fulluri '=>TRUE));256 if(preg_match("/(^https:\/\/)/i", $url)!=false){257 $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false);258 }259 $context = stream_context_create($options);260 $res = file_get_contents($lookup_url,false,$context);*/261 354 $htmlparser = new ExpressCurate_HtmlParser($lookup_url); 262 355 $res = $htmlparser->download(); … … 269 362 return false; 270 363 } 364 365 271 366 272 367 public function get_feed_content() 273 368 { 274 $feed_array = array(); 369 // read the existing feed to modify below 370 $feedContent = get_option('expresscurate_feed_content'); 371 if (empty($feedContent)) { 372 $feed_array = array(); 373 } else { 374 $feedContent = json_decode($feedContent, true); 375 $feed_array = $feedContent['content']; 376 } 377 378 // blabla 275 379 $data = $_REQUEST; 276 $date = urldecode($date["date"]); 380 $pull_feed_interval = (get_option('expresscurate_pull_hours_interval')) ? get_option('expresscurate_pull_hours_interval') : 1; 381 $date = ($data["date"]) ? urldecode($data["date"]) : date('Y-m-d H:i:s', strtotime("-" . $pull_feed_interval . " hour")); 277 382 $curated_links_rss = get_option('expresscurate_links_rss', ''); 278 383 if ($curated_links_rss) { 384 // get the deleted suggestions 385 $deleted_urls = array(); 386 $feed_content_deleted = get_option('expresscurate_feed_content_deleted', ''); 387 if (empty($feed_content_deleted)) { 388 $feed_content_deleted = array(); 389 } else { 390 $feed_content_deleted = json_decode($feed_content_deleted, true); 391 } 392 if (is_array($feed_content_deleted)) { 393 foreach ($feed_content_deleted as $deletet_item) { 394 $deleted_urls[] = $deletet_item; 395 } 396 } 397 398 // go over the feeds and try to pull 279 399 $curated_links_rss = json_decode($curated_links_rss, true); 280 $deleted_urls = array();281 if (!isset($date)) {282 $feed_content_deleted = get_option('expresscurate_feed_content_deleted', '');283 if ($feed_content_deleted) {284 $feed_content_deleted = json_decode($feed_content_deleted, true);285 }286 if (is_array($feed_content_deleted)) {287 foreach ($feed_content_deleted as $deletet_item) {288 $deleted_urls[] = $deletet_item['link'];289 }290 }291 }292 400 if (count($curated_links_rss)) { 293 401 foreach ($curated_links_rss as $url => $feed_url) { 402 // pull content 294 403 $lookup_url = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=" . urlencode($feed_url['feed_url']); 295 //$result= json_decode(file_get_contents($lookup_url), true);296 404 $htmlparser = new ExpressCurate_HtmlParser($lookup_url); 297 405 $res = $htmlparser->download(); 406 // decode and collect 298 407 $result = json_decode($res, true); 299 408 $this->collect_feed($result, $deleted_urls, $feed_array, 'feed', $date); … … 301 410 } 302 411 303 @uasort($feed_array, array($this, "feedSortByDate")); 304 412 // check if the feed is empty and sort 413 if(!empty($feed_array)) { 414 @uasort($feed_array, array($this, "feedSortByDate")); 415 416 // check if the feed is full or not 417 if(count($feed_array) > self::CONTENT_FEED_MAX_SIZE) { 418 // remove the last elements 419 $feed_array = array_slice($feed_array,0,self::CONTENT_FEED_MAX_SIZE); 420 // TODO implement 421 422 } 423 } 424 425 // save the latest feed 305 426 $feed_content = json_encode(array('date' => date('Y-m-d H:i:s'), 'content' => $feed_array)); 306 update_option('expresscurate_feed_content', $feed_content);427 // update_option('expresscurate_feed_content', $feed_content); 307 428 return $feed_content; 308 429 } 309 310 311 } 312 313 public function manual_pull_feed(){ 314 $feeds = json_decode($this->get_feed_content(),true); 315 if(!empty($feeds['content'])){ 316 wp_clear_scheduled_hook('expresscurate_pull_feeds'); 317 $pull_feed_interval = (get_option('expresscurate_pull_hours_interval'))?get_option('expresscurate_pull_hours_interval'):1; 318 wp_schedule_event(strtotime("+".$pull_feed_interval." hour"), 'hourly', 'expresscurate_pull_feeds'); 319 $feeds["minutes_to_next_pull"]= human_time_diff(wp_next_scheduled('expresscurate_pull_feeds'),time()); 320 } 321 echo json_encode($feeds); 322 die; 323 } 324 325 public function filter_feeds_by_date(){ 326 $data = $_REQUEST; 327 $feed_content = json_decode(get_option('expresscurate_feed_content', ''), true); 328 $filtered_feeds = array(); 329 if(isset($data['date']) && !empty($feed_content['content'])){ 330 foreach($feed_content['content'] as $link => $feed){ 331 if((strtotime($feed['date']) - $data['date']) >= 0){ 332 $filtered_feeds[$link] = $feed; 333 } 334 } 335 } 336 return $filtered_feeds; 337 } 338 339 public function send_content_alert() 340 { 341 342 if (get_option('expresscurate_enable_content_alert') == 'on') { 343 $feed_content = json_decode(get_option('expresscurate_feed_content', ''), true); 344 345 if ($this->date_diff(date('Y-m-d H:i:s'), get_option('expresscurate_content_alert_lastDate', true)) > get_option('expresscurate_content_alert_frequency', true) 346 && isset($feed_content['content']) && $feed_content['content'] !== NULL 347 ) { 348 349 $emailStories = array(); 350 foreach ($feed_content['content'] as $link => $story) { 351 if (isset($story['keywords'])) { 352 if ($this->date_diff(get_option('expresscurate_content_alert_lastDate', true), $story['date'], false) < 0) { 353 $emailStories[$link] = $story; 354 } 355 } 356 } 357 if (!empty($emailStories)) { 358 $expressCurateEmail = new ExpressCurate_Email(); 359 $expressCurateEmail->sendContentAlertEmail($emailStories); 360 361 } 362 363 } 364 } 365 366 } 367 368 public function collect_feed($result, $deleted_urls, &$feed_array, $type = 'feed', $date = false) 430 } 431 432 private function collect_feed($result, $deleted_urls, &$feed_array, $type = 'feed', $date = false) 369 433 { 370 434 $feeds = array(); … … 377 441 } 378 442 foreach ($feeds as $story) { 379 if ((isset($story['link']) && !in_array($story['link'], $deleted_urls)) || (isset($story['address']) && !in_array($story['address'], $deleted_urls))) { 380 $link = isset($story['link']) ? $story['link'] : $story['address']; 443 // get the post url 444 $link = isset($story['link']) ? $story['link'] : $story['address']; 445 if(empty($link) || isset($deleted_urls[$link])) { 446 continue; 447 } 448 449 // parse the post url 450 $parsedLink = parse_url($link); 451 452 // google alerts support 453 // check for google redirect urls and pick up the original post link 454 $protocol = $parsedLink['scheme']; 455 if (strpos($protocol . "://www.google.com/url", $url) == 0) { 456 $url_query = explode("&", $query); 457 foreach ($url_query as $param) { 458 if (strpos($param, 'url=') === 0) { 459 $link = str_replace("url=", "", $param); 460 $link = urldecode($link); 461 $parsedLink = parse_url($link); 462 break; 463 } 464 } 465 } 466 467 // check if this link is already in the feed 468 if(isset($feed_array[$link])) { 469 continue; 470 } 471 381 472 $domain = parse_url($link); 382 if (preg_match('/(?P<subdomain>.<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $ domain['host'], $regs)) {473 if (preg_match('/(?P<subdomain>.<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $parsedLink['host'], $regs)) { 383 474 $domain = $regs['domain']; 384 475 } else { 385 476 $domain = $domain['host']; 386 477 } 478 479 // download and analyze 387 480 $html_parser = new ExpressCurate_HtmlParser($link); 481 $link = $html_parser->getRealURL(); 482 // check if the final page (initial or redirected address) is already in feed 483 if(isset($feed_array[$link])) { 484 continue; 485 } 486 388 487 $keywords = $html_parser->analyzeKeywords(); 389 488 $media = $html_parser->containsMedia(); 489 390 490 $publishDate = isset($story['publishedDate']) ? $story['publishedDate'] : $story['date']; 391 491 $expressCurateDate = new ExpressCurate_Date(); 392 492 $publishDate = $expressCurateDate->dateWithTimeUtc(strtotime($publishDate)); 493 393 494 $story_array = array( 394 495 'title' => $story['title'], … … 416 517 $feed_array[$link] = $story_array; 417 518 } 418 419 } 420 } 519 } 520 } 521 522 public function manual_pull_feed() { 523 // get feed data 524 $feeds = json_decode($this->get_feed_content(), true); 525 526 // reschedule the cronjob 527 if(!empty($feeds['content'])) { 528 wp_clear_scheduled_hook('expresscurate_pull_feeds'); 529 $pull_feed_interval = (get_option('expresscurate_pull_hours_interval')) ? get_option('expresscurate_pull_hours_interval') : 1; 530 wp_schedule_event(strtotime("+" . $pull_feed_interval . " hour"), 'hourly', 'expresscurate_pull_feeds'); 531 $feeds["minutes_to_next_pull"] = human_time_diff(wp_next_scheduled('expresscurate_pull_feeds'), time()); 532 } 533 534 // return 535 echo json_encode($feeds); 536 die; 537 } 538 539 public function show_content_feed_items() 540 { 541 include(sprintf("%s/templates/feed_list.php", dirname(__FILE__))); 542 die; 543 } 544 545 public function filter_feeds_by_date() { 546 $data = $_REQUEST; 547 $feed_content = json_decode(get_option('expresscurate_feed_content', ''), true); 548 $filtered_feeds = array(); 549 if(isset($data['date']) && !empty($feed_content['content'])){ 550 foreach($feed_content['content'] as $link => $feed){ 551 if((strtotime($feed['date']) - $data['date']) >= 0){ 552 $filtered_feeds[$link] = $feed; 553 } 554 } 555 } 556 return $filtered_feeds; 557 } 558 559 public function send_content_alert() 560 { 561 562 if (get_option('expresscurate_enable_content_alert') == 'on') { 563 $feed_content = json_decode(get_option('expresscurate_feed_content', ''), true); 564 565 if ($this->date_diff(date('Y-m-d H:i:s'), get_option('expresscurate_content_alert_lastDate', true)) > get_option('expresscurate_content_alert_frequency', true) 566 && isset($feed_content['content']) && $feed_content['content'] !== NULL 567 ) { 568 569 $emailStories = array(); 570 foreach ($feed_content['content'] as $link => $story) { 571 if (!empty($story['keywords'])) { 572 if ($this->date_diff(get_option('expresscurate_content_alert_lastDate', true), $story['date'], false) < 0) { 573 $emailStories[$link] = $story; 574 } 575 } 576 } 577 if (!empty($emailStories)) { 578 $expressCurateEmail = new ExpressCurate_Email(); 579 $expressCurateEmail->sendContentAlertEmail($emailStories); 580 581 } 582 583 } 584 } 585 421 586 } 422 587 -
expresscurate/trunk/ExpressCurate_GoogleAuth.php
r1106118 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 4 5 /* 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 10 */ 3 11 4 12 class ExpressCurate_GoogleAuth -
expresscurate/trunk/ExpressCurate_HtmlParser.php
r1129694 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 3 4 … … 9 10 */ 10 11 11 class ExpressCurate_HtmlParser { 12 // resource details 13 private $url; 14 private $domain; 15 private $fragment; 16 private $protocol; 17 private $path; 18 private $raw; 19 private $referer; 20 21 // may be an html or a raw data (used for images, etc) 22 private $data = null; 23 private $dataHTTPStatus = null; 24 private $dataUTF8 = null; 25 26 // html dom details 27 private $dom = null; 28 private $article = null; 29 private $xpath = null; 30 31 // article details 32 private $title = null; 33 private $keywords = null; 34 private $description = null; 35 36 // asynch download settings 37 private $asynchHandle = null; 38 private static $ASYNC_SUPPORT_CURL_MULTI_HANDLER = null; 39 private static $REQUEST_TIMEOUT = 10; 40 41 public static function supportsAsynch() { 12 class ExpressCurate_HtmlParser 13 { 14 // resource details 15 private $url; 16 private $domain; 17 private $fragment; 18 private $protocol; 19 private $path; 20 private $raw; 21 private $referer; 22 23 // may be an html or a raw data (used for images, etc) 24 private $data = null; 25 private $dataHTTPStatus = null; 26 private $dataUTF8 = null; 27 28 // html dom details 29 private $dom = null; 30 private $article = null; 31 private $xpath = null; 32 33 // article details 34 private $title = null; 35 private $keywords = null; 36 private $description = null; 37 38 // asynch download settings 39 private $asynchHandle = null; 40 private static $ASYNC_SUPPORT_CURL_MULTI_HANDLER = null; 41 private static $REQUEST_TIMEOUT = 10; 42 43 public static function supportsAsynch() 44 { 42 45 return is_callable('curl_init'); 43 } 44 45 public static function supportsDownload() { 46 return is_callable('curl_init') || preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); 47 } 48 49 public function __construct($url, $raw = false, $referer = null) { 50 if($url) { 51 $parsedURL = parse_url($url); 52 53 $path = $parsedURL['path']; 54 $lastof = strrpos($path, "/"); 55 $path = substr($path, 0, $lastof); 56 57 $this->domain = 'http://' . $parsedURL['host']; 58 $this->path = 'http://' . $parsedURL['host'] . "/" . $path . "/"; 59 $this->fragment = $parsedURL['fragment']; 60 $this->protocol = $parsedURL['scheme']; 61 $query = $parsedURL['query']; 62 63 // google redirection fix 64 if(strpos($this->protocol . "://www.google.com/url", $url)==0) { 65 $url_query = explode("&", $query); 66 foreach($url_query as $param) { 67 if(strpos($param, 'url=') === 0) { 68 $url = str_replace("url=", "", $param); 69 $url = urldecode($url); 70 break; 71 } 72 } 73 } 74 $this->url = html_entity_decode($url); 75 } 76 $this->raw = $raw; 77 $this->referer = $referer; 78 } 79 80 public function getFile() { 81 if(self::supportsAsynch()) { 82 $this->downloadAsynch(); 83 self::ensureAsynchData(); 84 return $this->getAsynchData(); 85 } else { 86 return $this->download(); 87 } 88 } 89 90 public function getHTTPStatus() { 91 return $this->dataHTTPStatus; 92 } 93 94 public function isHTTPStatusOK() { 95 if ((is_array($this->dataHTTPStatus) && ($this->dataHTTPStatus[0] == "HTTP/1.1 200 OK" || strpos($this->dataHTTPStatus[0], '200'))) || $this->dataHTTPStatus == "HTTP/1.1 200 OK" || $this->dataHTTPStatus == 200 || $this->dataHTTPStatus == 'HTTP\/1.1 200 OK') { 96 return true; 97 } 98 return false; 99 } 100 101 public function getHTTPStatusCode() { 102 if($this->isHTTPStatusOK()) { 103 return 200; 104 } 105 106 if ((is_array($this->dataHTTPStatus) && ($this->dataHTTPStatus[0] == "HTTP/1.1 403 Forbidden" || strpos($this->dataHTTPStatus[0], '403'))) || $this->dataHTTPStatus == "HTTP/1.1 403 Forbidden" || $this->dataHTTPStatus == 403) { 107 return 403; 108 } 109 110 return $http_response_header[0]; 111 } 112 113 public function downloadAsynch() { 114 if($this->data != null) { 115 return; 116 } 117 118 if(self::supportsAsynch() == false) { 119 return $this->download(); 120 } 121 122 if(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER == null) { 123 $mh = curl_multi_init(); 124 set_time_limit(0); 125 126 self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER = $mh; 127 } 128 129 // setup the single curl 130 $ch = $this->createCURL($this->url); 131 132 // add the single handle to the multi handle 133 curl_multi_add_handle(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $ch); 134 // start the download 135 curl_multi_exec(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $running); 136 137 // keep the handle for later 138 $this->asynchHandle = $ch; 139 } 140 141 private function createCURL($url) { 142 $ch = curl_init(); 143 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 144 curl_setopt($ch, CURLOPT_URL, $url); 145 curl_setopt($ch, CURLOPT_USERAGENT, ExpressCurate_Actions::USER_AGENT); 146 if($this->referer) { 147 curl_setopt($ch, CURLOPT_REFERER, $this->referer); 148 } 149 curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/xhtml+xml, application/xml", "Accept-Charset: utf-8")); 150 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 151 curl_setopt($ch, CURLOPT_TIMEOUT, self::$REQUEST_TIMEOUT); 152 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 153 curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 154 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 155 } 156 157 private static function ensureAsynchData() { 158 do { 159 curl_multi_exec(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $running); 160 } while($running > 0); 161 } 162 163 private function getAsyncData() { 164 $content = curl_multi_getcontent($this->asynchHandle); 165 $this->dataHTTPStatus = curl_getinfo($this->asynchHandle, CURLINFO_HTTP_CODE); 166 $contentType = curl_getinfo($this->asynchHandle, CURLINFO_CONTENT_TYPE); 167 168 curl_multi_remove_handle(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $this->asynchHandle); 169 170 if(!$this->raw) { 171 $content = self::sanitizeContent($content); 172 173 if($contentType) { 174 list($charset, $encoding) = explode("=", $contentType); 175 $encoding = strtoupper(trim($encoding)); 176 177 $supportedEncoding = array_search($encoding, mb_list_encodings()) !== false; 178 179 if(!$supportedEncoding) { 180 $encoding = mb_detect_encoding($content); 181 } 182 183 $content = mb_convert_encoding($content, 'UTF-8', $encoding); 184 $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); 185 } 186 } 187 188 $this->data = $content; 189 190 return $this->data; 191 } 192 193 public function download() { 194 if($this->data != null) { 195 return; 196 } 197 46 } 47 48 public static function supportsDownload() 49 { 50 return is_callable('curl_init') || preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); 51 } 52 53 public function __construct($url, $raw = false, $referer = null) 54 { 55 if ($url) { 56 $parsedURL = parse_url($url); 57 58 $path = $parsedURL['path']; 59 $lastof = strrpos($path, "/"); 60 $path = substr($path, 0, $lastof); 61 62 $this->domain = 'http://' . $parsedURL['host']; 63 $this->path = 'http://' . $parsedURL['host'] . "/" . $path . "/"; 64 $this->fragment = $parsedURL['fragment']; 65 $this->protocol = $parsedURL['scheme']; 66 $query = $parsedURL['query']; 67 68 // google redirection fix 69 if (strpos($this->protocol . "://www.google.com/url", $url) == 0) { 70 $url_query = explode("&", $query); 71 foreach ($url_query as $param) { 72 if (strpos($param, 'url=') === 0) { 73 $url = str_replace("url=", "", $param); 74 $url = urldecode($url); 75 break; 76 } 77 } 78 } 79 $this->url = html_entity_decode($url); 80 } 81 $this->raw = $raw; 82 $this->referer = $referer; 83 } 84 85 public function getFile() 86 { 87 if (self::supportsAsynch()) { 88 $this->downloadAsynch(); 89 self::ensureAsynchData(); 90 return $this->getAsynchData(); 91 } else { 92 return $this->download(); 93 } 94 } 95 96 public function getHTTPStatus() 97 { 98 return $this->dataHTTPStatus; 99 } 100 101 public function isHTTPStatusOK() 102 { 103 if ((is_array($this->dataHTTPStatus) && ($this->dataHTTPStatus[0] == "HTTP/1.1 200 OK" || strpos($this->dataHTTPStatus[0], '200'))) || $this->dataHTTPStatus == "HTTP/1.1 200 OK" || $this->dataHTTPStatus == 200 || $this->dataHTTPStatus == 'HTTP\/1.1 200 OK') { 104 return true; 105 } 106 if (is_array($this->dataHTTPStatus) && ($this->dataHTTPStatus[0] == "HTTP/1.1 301 Moved Permantenly" || strpos($this->dataHTTPStatus[0], '301')) || ($this->dataHTTPStatus[0] == "HTTP/1.1 302 Found" || strpos($this->dataHTTPStatus[0], '302')) || ($this->dataHTTPStatus[0] == "HTTP/1.1 303 See Other" || strpos($this->dataHTTPStatus[0], '303')) || ($this->dataHTTPStatus[0] == "HTTP/1.1 307 Temporary Redirect" || strpos($this->dataHTTPStatus[0], '307')) || ($this->dataHTTPStatus[0] == "HTTP/1.1 308 Permanent Redirect" || strpos($this->dataHTTPStatus[0], '308'))){ 107 return true; 108 } 109 return false; 110 } 111 112 public function getHTTPStatusCode() 113 { 114 if ($this->isHTTPStatusOK()) { 115 return 200; 116 } 117 118 if ((is_array($this->dataHTTPStatus) && ($this->dataHTTPStatus[0] == "HTTP/1.1 403 Forbidden" || strpos($this->dataHTTPStatus[0], '403'))) || $this->dataHTTPStatus == "HTTP/1.1 403 Forbidden" || $this->dataHTTPStatus == 403) { 119 return 403; 120 } 121 122 return $http_response_header[0]; 123 } 124 125 public function downloadAsynch() 126 { 127 if ($this->data != null) { 128 return; 129 } 130 131 if (self::supportsAsynch() == false) { 132 return $this->download(); 133 } 134 135 if (self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER == null) { 136 $mh = curl_multi_init(); 137 set_time_limit(0); 138 139 self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER = $mh; 140 } 141 142 // setup the single curl 143 $ch = $this->createCURL($this->url); 144 145 // add the single handle to the multi handle 146 curl_multi_add_handle(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $ch); 147 // start the download 148 curl_multi_exec(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $running); 149 150 // keep the handle for later 151 $this->asynchHandle = $ch; 152 } 153 154 private function createCURL($url) 155 { 156 $ch = curl_init(); 157 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 158 curl_setopt($ch, CURLOPT_URL, $url); 159 curl_setopt($ch, CURLOPT_USERAGENT, ExpressCurate_Actions::USER_AGENT); 160 if ($this->referer) { 161 curl_setopt($ch, CURLOPT_REFERER, $this->referer); 162 } 163 curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/xhtml+xml, application/xml", "Accept-Charset: utf-8")); 164 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 165 curl_setopt($ch, CURLOPT_TIMEOUT, self::$REQUEST_TIMEOUT); 166 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 167 curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 168 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 169 } 170 171 private static function ensureAsynchData() 172 { 173 do { 174 curl_multi_exec(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $running); 175 } while ($running > 0); 176 } 177 178 private function getAsyncData() 179 { 180 $content = curl_multi_getcontent($this->asynchHandle); 181 $this->dataHTTPStatus = curl_getinfo($this->asynchHandle, CURLINFO_HTTP_CODE); 182 $contentType = curl_getinfo($this->asynchHandle, CURLINFO_CONTENT_TYPE); 183 184 curl_multi_remove_handle(self::$ASYNC_SUPPORT_CURL_MULTI_HANDLER, $this->asynchHandle); 185 186 if (!$this->raw) { 187 $content = self::sanitizeContent($content); 188 189 if ($contentType) { 190 list($charset, $encoding) = explode("=", $contentType); 191 $encoding = strtoupper(trim($encoding)); 192 193 $supportedEncoding = array_search($encoding, mb_list_encodings()) !== false; 194 195 if (!$supportedEncoding) { 196 $encoding = mb_detect_encoding($content); 197 } 198 199 $content = mb_convert_encoding($content, 'UTF-8', $encoding); 200 $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); 201 } 202 } 203 204 $this->data = $content; 205 206 return $this->data; 207 } 208 209 210 public function getRealURL(){ 211 foreach(get_headers($this->url) as $header) { 212 if (strpos($header, "Location:") === 0) { 213 $this->url = trim(substr($header, 9)); 214 } 215 } 216 return $this->url; 217 } 218 219 public function download() 220 { 221 if ($this->data != null) { 222 return; 223 } 224 198 225 // if (self::supportsAsynch()) { 199 226 // // setup the single curl … … 204 231 // curl_close($ch); 205 232 // } else { 206 $header = ''; 207 if($this->referer) { 208 $header .= 'Referer: ' . $this->referer . '\r\n'; 209 } 210 if(!$this->raw) { 211 $header .= 'Accept: application/xhtml+xml, application/xml, text/html\r\n'; 212 $header .= 'Accept-Charset: UTF-8'; 213 } 214 $options = array('http' => array( 215 'user_agent' => ExpressCurate_Actions::USER_AGENT, 216 'follow_location' => 1, 217 'max_redirects' => 5, 218 'request_fulluri '=> TRUE, 219 'timeout' => self::$REQUEST_TIMEOUT, 220 'header' => $header)); 221 if(strpos($this->url, 'https://') === 0) { 222 $options['ssl'] = array('verify_peer' => false, 'verify_peer_name' => false); 223 } 224 $context = stream_context_create($options); 225 $content = file_get_contents($this->url, false, $context); 226 // $http_response_header gets loaded once file get contents is called, php native stuff 227 $this->dataHTTPStatus = $http_response_header; 228 229 // try to resolve the content encoding if text/html content 230 if(!$this->raw) { 231 if(!empty($http_response_header)) { 232 foreach ($http_response_header as $header) { 233 if (substr(strtolower($header), 0, 13) == "content-type:") { 234 $contentTypeData = explode(";", $header); 235 if (count($contentTypeData) == 2) { 236 list($contentTypeKey, $contentType) = $contentTypeData; 237 } 238 } 239 } 240 } 241 } 233 set_time_limit(0); 234 $header = ''; 235 if ($this->referer) { 236 $header .= 'Referer: ' . $this->referer . '\r\n'; 237 } 238 if (!$this->raw) { 239 $header .= 'Accept: application/xhtml+xml, application/xml, text/html\r\n'; 240 $header .= 'Accept-Charset: UTF-8'; 241 } 242 $options = array('http' => array( 243 'user_agent' => ExpressCurate_Actions::USER_AGENT, 244 'follow_location' => 1, 245 'max_redirects' => 5, 246 'request_fulluri ' => TRUE, 247 'timeout' => self::$REQUEST_TIMEOUT, 248 'header' => $header)); 249 if (strpos($this->url, 'https://') === 0) { 250 $options['ssl'] = array('verify_peer' => false, 'verify_peer_name' => false); 251 } 252 $context = stream_context_create($options); 253 $content = @file_get_contents($this->url, false, $context); 254 255 // $http_response_header gets loaded once file get contents is called, php native stuff 256 $this->dataHTTPStatus = $http_response_header; 257 258 // try to resolve the content encoding if text/html content 259 if (!$this->raw) { 260 if (!empty($http_response_header)) { 261 foreach ($http_response_header as $header) { 262 if (substr(strtolower($header), 0, 13) == "content-type:") { 263 $contentTypeData = explode(";", $header); 264 if (count($contentTypeData) == 2) { 265 list($contentTypeKey, $contentType) = $contentTypeData; 266 } 267 } 268 } 269 } 270 } 242 271 // } 243 272 244 // make sure if there is a response at all 245 if($this->isHTTPStatusOK() === false) { 246 // terminate 247 $this->data = null; 248 return null; 249 } 250 251 // there is data with OK code, process if required 252 if(!$this->raw) { 253 $content = self::sanitizeContent($content); 254 255 if($contentType) { 256 list($charset, $encoding) = explode("=", $contentType); 257 $encoding = strtoupper(trim($encoding)); 258 259 $supportedEncoding = array_search($encoding, mb_list_encodings()) !== false; 260 261 if(!$supportedEncoding) { 262 $encoding = mb_detect_encoding($content); 263 } 264 265 $content = mb_convert_encoding($content, 'UTF-8', $encoding); 266 $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); 267 } 268 } 269 270 // save and return 271 $this->data = $content; 272 return $this->data; 273 } 274 275 private static function sanitizeContent($content) { 276 $content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $content); 277 $content = preg_replace('/<--[\S\s]*?-->/msi', '', $content); 278 $content = preg_replace('/(<noscript[^>]*>|<\/noscript>)/msi', '', $content); 279 $content = preg_replace('~>\s+<~', '><', $content); 280 $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $content); 281 282 $content = preg_replace('/^.*(?=<html>)/i', '', $content); 283 $content = str_replace("\0", " ", $content); 273 // make sure if there is a response at all 274 if ($this->isHTTPStatusOK() === false) { 275 // terminate 276 $this->data = null; 277 return null; 278 } 279 280 // there is data with OK code, process if required 281 if (!$this->raw) { 282 $content = self::sanitizeContent($content); 283 284 if ($contentType) { 285 list($charset, $encoding) = explode("=", $contentType); 286 $encoding = strtoupper(trim($encoding)); 287 288 $supportedEncoding = array_search($encoding, mb_list_encodings()) !== false; 289 290 if (!$supportedEncoding) { 291 $encoding = mb_detect_encoding($content); 292 } 293 294 $content = mb_convert_encoding($content, 'UTF-8', $encoding); 295 $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); 296 } 297 } 298 299 // save and return 300 $this->data = $content; 301 return $this->data; 302 } 303 304 private static function sanitizeContent($content) 305 { 306 $content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $content); 307 $content = preg_replace('/<--[\S\s]*?-->/msi', '', $content); 308 $content = preg_replace('/(<noscript[^>]*>|<\/noscript>)/msi', '', $content); 309 $content = preg_replace('~>\s+<~', '><', $content); 310 $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $content); 311 312 $content = preg_replace('/^.*(?=<html>)/i', '', $content); 313 $content = str_replace("\0", " ", $content); 314 315 return $content; 316 } 317 318 private function parseDom() 319 { 320 if ($this->dom == null) { 321 // initialize 322 $dom = new DOMDocument('1.0', 'UTF-8'); 323 @$dom->loadHTML($this->data); 324 325 // cleanup 326 $this->removeElementsByTagName('script', $dom); 327 $this->removeElementsByTagName('style', $dom); 328 $this->removeElementsByTagName('link', $dom); 329 330 // assign 331 $this->dom = $dom; 332 $this->xpath = new DomXPath($dom); 333 } 334 } 335 336 private function removeElementsByTagName($tagName, $document) 337 { 338 $nodeList = $document->getElementsByTagName($tagName); 339 for ($nodeIdx = $nodeList->length; --$nodeIdx >= 0;) { 340 $node = $nodeList->item($nodeIdx); 341 $node->parentNode->removeChild($node); 342 } 343 } 344 345 private function parseArticle() 346 { 347 if ($this->article == null) { 348 // TODO check the xpath object problem, the final article shall support the same query method 349 350 $article = $this->dom->getElementsByTagName('article')->item(0); 351 352 if (empty($article)) { 353 $article = $this->xpath->query("//*[contains(@class, 'hentry')]")->item(0); 354 } 355 356 if (empty($article)) { 357 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/Article')]")->item(0); 358 } 359 360 if (empty($article)) { 361 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/TechArticle')]")->item(0); 362 } 363 364 if (empty($article)) { 365 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/ScholarlyArticle')]")->item(0); 366 } 367 368 if (empty($article)) { 369 $article = $this->dom->getElementsByTagName('body')->item(0); 370 } 371 372 $this->article = $article; 373 } 374 } 375 376 public function file_get_contents_utf8($url, $get_http_status = false, $set_utf8 = true) 377 { 378 $content = ''; 379 $charset = ''; 380 $utf8 = false; 381 $timeout = 10; 382 set_time_limit(0); 383 $user_agent = ExpressCurate_Actions::USER_AGENT; 384 $file_get_enabled = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); 385 if (strpos(parse_url($url, PHP_URL_SCHEME) . "://www.google.com/url", $url) == 0) { 386 $url_query = explode("&", parse_url($url, PHP_URL_QUERY)); 387 foreach ($url_query as $param) { 388 if (strpos($param, 'url=') === 0) { 389 $url = str_replace("url=", "", $param); 390 $url = urldecode($url); 391 break; 392 } 393 } 394 } 395 $normalized_url = html_entity_decode($url); 396 if (self::supportsAsynch()) { 397 $ch = curl_init(); 398 //curl_setopt($ch, CURLOPT_HEADER, 1); 399 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 400 curl_setopt($ch, CURLOPT_URL, $normalized_url); 401 curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); 402 403 // TODO fix the accepts header 404 curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: text/xml;charset=\"utf-8\"")); 405 406 // TODO configure the return transfer based on asynch choice 407 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 408 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 409 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 410 curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 411 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 412 $content = curl_exec($ch); 413 414 // TODO check if the content shall be transformed to UTF8 415 416 $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 417 curl_close($ch); 418 } elseif ($file_get_enabled) { 419 /*$options = (preg_match("/(^https:\/\/)/i", $url, $options)!=false)?array('ssl' => array('verify_peer'=> false,"verify_peer_name"=>false)):array('http' => array('user_agent' => $user_agent));*/ 420 $options = array('http' => array('user_agent' => $user_agent, ' follow_location' => 1, 'max_redirects' => 5, 'request_fulluri ' => TRUE, 'timeout' => $timeout)); 421 if (preg_match("/(^https:\/\/)/i", $url) != false) { 422 $options['ssl'] = array('verify_peer' => false, "verify_peer_name" => false); 423 } 424 $context = stream_context_create($options); 425 $content = file_get_contents($normalized_url, false, $context); 426 // $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8"); 427 $http_status = $http_response_header; 428 429 if (!empty($http_response_header)) { 430 foreach ($http_response_header as $header) { 431 if (substr(strtolower($header), 0, 13) == "content-type:") { 432 if (count(explode(";", $header)) > 1) { 433 list($contentType, $charset) = explode(";", $header); 434 } 435 } 436 } 437 } 438 439 $headers = headers_list(); 440 // get the content type header 441 foreach ($headers as $header) { 442 if (substr(strtolower($header), 0, 13) == "content-type:") { 443 list($contentType, $charset) = explode(";", trim(substr($header, 14), 2)); 444 if (strtolower(trim($charset)) == "charset=utf-8") { 445 $utf8 = true; 446 } 447 } 448 } 449 if ($charset && strpos(strtolower($charset), 'utf-8')) { 450 $utf8 = true; 451 } else { 452 $charset = mb_detect_encoding($content); 453 if (strpos(strtolower($charset), 'utf-8')) { 454 $utf8 = true; 455 } 456 } 457 if (!$utf8 && $set_utf8) { 458 $content = utf8_encode($content); 459 } 460 } else { 461 $data = array('status' => 'warning', 'msg' => 'Content from this page cannot be loaded. Please enable \"allow_url_open\" in php.ini.'); 462 echo json_encode($data); 463 die(); 464 } 465 if (!$get_http_status) { 466 return $content; 467 } else { 468 return array('content' => $content, 'http_status' => $http_status); 469 } 470 } 471 472 public function getContents() 473 { 474 $this->download(); 475 476 if (strlen($this->data) > 3) { 477 // prepare some data before getting contents 478 $this->title = $this->getTitle(); 479 $this->keywords = $this->getKeywords(); 480 $this->description = $this->getDescription(); 481 482 // get the contents 483 return $this->getElementsByTags(); 484 } else { 485 return false; 486 } 487 } 284 488 285 return $content; 286 } 287 288 private function parseDom() { 289 if($this->dom == null) { 290 // initialize 291 $dom = new DOMDocument('1.0', 'UTF-8'); 292 @$dom->loadHTML($this->data); 293 294 // cleanup 295 $this->removeElementsByTagName('script', $dom); 296 $this->removeElementsByTagName('style', $dom); 297 $this->removeElementsByTagName('link', $dom); 298 299 // assign 300 $this->dom = $dom; 301 $this->xpath = new DomXPath($dom); 302 } 303 } 304 305 private function removeElementsByTagName($tagName, $document) { 306 $nodeList = $document->getElementsByTagName($tagName); 307 for ($nodeIdx = $nodeList->length; --$nodeIdx >= 0;) { 308 $node = $nodeList->item($nodeIdx); 309 $node->parentNode->removeChild($node); 310 } 311 } 312 313 private function parseArticle() { 314 if($this->article == null) { 315 // TODO check the xpath object problem, the final article shall support the same query method 316 317 $article = $this->dom->getElementsByTagName('article')->item(0); 318 319 if(empty($article)) { 320 $article = $this->xpath->query("//*[contains(@class, 'hentry')]")->item(0); 321 } 322 323 if(empty($article)) { 324 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/Article')]")->item(0); 325 } 326 327 if(empty($article)) { 328 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/TechArticle')]")->item(0); 329 } 330 331 if(empty($article)) { 332 $article = $this->xpath->query("//*[contains(@itemtype, 'http://schema.org/ScholarlyArticle')]")->item(0); 333 } 334 335 if(empty($article)) { 336 $article = $this->dom->getElementsByTagName('body')->item(0); 337 } 338 339 $this->article = $article; 340 } 341 } 342 343 public function file_get_contents_utf8($url, $get_http_status = false, $set_utf8 = true) { 344 $content = ''; 345 $charset = ''; 346 $utf8 = false; 347 $timeout=10; 348 set_time_limit(0); 349 $user_agent = ExpressCurate_Actions::USER_AGENT; 350 $file_get_enabled = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); 351 if(strpos(parse_url($url,PHP_URL_SCHEME)."://www.google.com/url",$url)==0) { 352 $url_query = explode("&",parse_url($url,PHP_URL_QUERY)); 353 foreach($url_query as $param) { 354 if(strpos($param, 'url=') === 0) { 355 $url = str_replace("url=", "", $param); 356 $url = urldecode($url); 357 break; 358 } 359 } 360 } 361 $normalized_url = html_entity_decode($url); 362 if (self::supportsAsynch()) { 363 $ch = curl_init(); 364 //curl_setopt($ch, CURLOPT_HEADER, 1); 365 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 366 curl_setopt($ch, CURLOPT_URL, $normalized_url); 367 curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); 368 369 // TODO fix the accepts header 370 curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: text/xml;charset=\"utf-8\"")); 371 372 // TODO configure the return transfer based on asynch choice 373 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 374 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 375 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 376 curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 377 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 378 $content = curl_exec($ch); 379 380 // TODO check if the content shall be transformed to UTF8 381 382 $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 383 curl_close($ch); 384 } elseif($file_get_enabled) { 385 /*$options = (preg_match("/(^https:\/\/)/i", $url, $options)!=false)?array('ssl' => array('verify_peer'=> false,"verify_peer_name"=>false)):array('http' => array('user_agent' => $user_agent));*/ 386 $options = array('http' => array('user_agent' => $user_agent,' follow_location'=>1,'max_redirects'=>5,'request_fulluri '=>TRUE,'timeout' => $timeout)); 387 if(preg_match("/(^https:\/\/)/i", $url)!=false){ 388 $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false); 389 } 390 $context = stream_context_create($options); 391 $content = file_get_contents($normalized_url, false, $context); 392 // $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8"); 393 $http_status = $http_response_header; 394 395 if(!empty($http_response_header)) { 396 foreach ($http_response_header as $header) { 397 if (substr(strtolower($header), 0, 13) == "content-type:") { 398 if (count(explode(";", $header)) > 1) { 399 list($contentType, $charset) = explode(";", $header); 400 } 401 } 402 } 403 } 404 405 $headers = headers_list(); 406 // get the content type header 407 foreach ($headers as $header) { 408 if (substr(strtolower($header), 0, 13) == "content-type:") { 409 list($contentType, $charset) = explode(";", trim(substr($header, 14), 2)); 410 if (strtolower(trim($charset)) == "charset=utf-8") { 411 $utf8 = true; 412 } 413 } 414 } 415 if ($charset && strpos(strtolower($charset), 'utf-8')) { 416 $utf8 = true; 417 } else { 418 $charset = mb_detect_encoding($content); 419 if (strpos(strtolower($charset), 'utf-8')) { 420 $utf8 = true; 421 } 422 } 423 if (!$utf8 && $set_utf8) { 424 $content = utf8_encode($content); 425 } 426 } else { 427 $data = array('status' => 'warning', 'msg' => 'Content from this page cannot be loaded. Please enable \"allow_url_open\" in php.ini.'); 428 echo json_encode($data); 429 die(); 430 } 431 if (!$get_http_status) { 432 return $content; 433 } else { 434 return array('content' => $content, 'http_status' => $http_status); 435 } 436 } 437 438 public function getContents() { 439 $this->download(); 489 public function getCloneContents() 490 { 491 $this->download(); 492 493 if (strlen($this->data) > 3) { 494 // prepare some data before getting contents 495 $this->title = $this->getTitle(); 496 $this->keywords = $this->getKeywords(); 497 498 // get the contents 499 return $this->cloneElements(); 500 } else { 501 return false; 502 } 503 } 504 505 private function getTitle() 506 { 507 $this->parseDom(); 508 509 $title = $this->xpath->query('//title')->item(0)->nodeValue; 510 511 return $title; 512 } 513 514 private function getKeywords() 515 { 516 // Get the 'content' attribute value in a <meta name="keywords" ... /> 517 $matches = array(); 518 $max_count = get_option("expresscurate_max_tags", 3); 519 // Search for <meta name="keywords" content="keyword1, keword2" /> 520 preg_match('/<meta.*?name=("|\')keywords("|\').*?content=("|\')(.*?)("|\')/i', $this->data, $matches); 521 if (count($matches) > 4) { 522 return array_filter(explode(",", trim($matches[4]))); 523 } 524 525 // Order of attributes could be swapped around: <meta content="keyword1, keword2" name="keywords" /> 526 preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')keywords("|\')/i', $this->data, $matches); 527 if (count($matches) > 2) { 528 return array_filter(explode(",", trim($matches[2]))); 529 } 530 531 // No match 532 return null; 533 } 534 535 private function getDescription() 536 { 537 // Get the 'content' attribute value in a <meta name="description" ... /> 538 $matches = array(); 539 540 // Search for <meta name="description" content="Buy my stuff" /> 541 preg_match('/<meta.*?name=("|\')description("|\').*?content=("|\')(.*?)("|\')/i', $this->data, $matches); 542 if (count($matches) > 4) { 543 return $matches[4]; 544 } 545 546 // Order of attributes could be swapped around: <meta content="Buy my stuff" name="description" /> 547 preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')description("|\')/i', $this->data, $matches); 548 if (count($matches) > 2) { 549 return $matches[2]; 550 } 551 552 // No match 553 return null; 554 } 555 556 private function getElementsByTags() 557 { 558 $this->parseDom(); 559 $this->parseArticle(); 560 561 // TODO make sure this cleanup can be done earlier or later, or maybe shall not affect the base dom with original html at all 562 563 $result_images = array(); 564 $result_paragraphs = array(); 565 $result_h1 = ''; 566 $result_h2 = ''; 567 $result_h3 = ''; 568 569 570 // TODO this is a new xpath with the new modified dom, not sure if this is required if dom is passed with a reference 571 $imgTags = $this->xpath->query(".//img",$this->article); 572 $i = 0; 573 foreach ($imgTags as $t) { 574 $src = $t->getAttribute('src'); 575 if (strlen($src) > 3) { 576 if (strpos($src, 'http://') !== false || strpos($src, 'https://') !== false) { 577 $src = $src; 578 } else if (strpos($src, '//') === 0) { 579 if (isset($this->fragment)) { 580 $src = $this->fragment . $src; 581 } else { 582 $src = $this->protocol . ":" . $src; 583 } 584 } elseif (strpos($src, '/') === 0) { 585 $src = $this->domain . $src; 586 } else { 587 $src = $this->path . $src; 588 } 589 590 $src = preg_replace('%([^:])([/]{2,})%', '\\1/', $src); 591 592 if (!in_array($src, $result_images)) { 593 $result_images[] = ($src); 594 } 595 $i++; 596 } 597 $t->parentNode->removeChild($t); 598 } 599 //get H1 600 $h1Tag = $this->xpath->query(".//h1",$this->article); 601 foreach ($h1Tag as $h1) { 602 if (strlen($h1->nodeValue) > 3) { 603 $result_h1 .= $h1->nodeValue . "\n"; 604 } 605 $h1->parentNode->removeChild($h1); 606 } 607 //get H2 608 $h2Tag = $this->xpath->query(".//h2",$this->article); 609 foreach ($h2Tag as $h2) { 610 if (strlen($h2->nodeValue) > 3) { 611 $result_h2 .= $h2->nodeValue . "\n"; 612 } 613 $h2->parentNode->removeChild($h2); 614 } 615 //get H3 616 $h3Tag = $this->xpath->query(".//h3",$this->article); 617 foreach ($h3Tag as $h3) { 618 if (strlen($h3->nodeValue) > 3) { 619 $result_h3 .= $h3->nodeValue . "\n"; 620 } 621 $h3->parentNode->removeChild($h3); 622 } 623 //get text 624 /*$i = 0; 625 $articleTags = $this->xpath->query('/html/body/article'); 626 foreach ($articleTags as $t) { 627 $result_paragraphs[$i]['value'] = strip_tags(trim($t->nodeValue)); 628 $result_paragraphs[$i]['tag'] = 'article'; 629 $t->parentNode->removeChild($t); 630 $i++; 631 }*/ 632 633 634 $textTags = $this->xpath->query('//text()',$this->article); 635 foreach ($textTags as $t) { 636 if ($t->length > 15 && $t->parentNode->tagName != 'a' && $t->parentNode->tagName != 'h1' && $t->parentNode->tagName != 'h2' && $t->parentNode->tagName != 'h3') { 637 if ($t->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->parentNode->nodeName == "blockquote") { 638 if ($t->parentNode->nodeName == "blockquote") { 639 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->nodeValue); 640 } elseif ($t->parentNode->parentNode && $t->parentNode->parentNode->nodeName == "blockquote") { 641 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->nodeValue); 642 } elseif ($t->parentNode->parentNode->parentNode && $t->parentNode->parentNode->parentNode->nodeName == "blockquote") { 643 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->parentNode->nodeValue); 644 } 645 $result_paragraphs[$i]['tag'] = "blockquote"; 646 } else { 647 $result_paragraphs[$i]['value'] = strip_tags($t->nodeValue); 648 $result_paragraphs[$i]['tag'] = $t->parentNode->nodeName; 649 } 650 $i++; 651 } 652 } 653 654 //author 655 $article_author = ''; 656 $author = $this->xpath->query('.//*[@rel="author"][1]',$this->article)->item(0); 657 if ($author) { 658 $article_author = $author->nodeValue; 659 } 660 //date 661 $article_date = ''; 662 $date = $this->xpath->query('.//*[@datetime][1]',$this->article)->item(0); 663 if ($date) { 664 $article_date = $date->nodeValue; 665 } 666 667 668 //smart tags 669 $max_count = get_option("expresscurate_max_tags", 3); 670 $smart_tags = array(); 671 672 $defined_tags = get_option("expresscurate_defined_tags", ''); 673 if ($defined_tags) { 674 $defined_tags = explode(",", $defined_tags); 675 foreach ($defined_tags as $tag) { 676 $tag = trim($tag); 677 $count = $this->countMatches($tag); 678 if ($count > 0) { 679 $smart_tags[$tag] = $count; 680 } 681 } 682 } 683 684 if (count($this->keywords)) { 685 foreach ($this->keywords as $key => $keyword) { 686 $count = $this->countMatches($key); 687 if ($count > 0) { 688 $smart_tags[$keyword] = $count; 689 } 690 } 691 } 692 693 if (count($smart_tags) > 0) { 694 arsort($smart_tags); 695 $smart_tags = array_slice(array_keys(array_reverse($smart_tags)), 0, $max_count); 696 } 697 698 $result_paragraphs_unique = $this->arrayUnique($result_paragraphs); 699 $media = $this->containsMedia(); 700 701 $result = array( 702 'title' => $this->title, 703 'headings' => array('h1' => $result_h1, 'h2' => $result_h2, 'h3' => $result_h3), 704 'metas' => array('description' => $this->description, 'keywords' => $smart_tags), 705 'images' => $result_images, 706 'media' => $media, 707 'paragraphs' => $result_paragraphs_unique, 708 'author' => $article_author, 709 'date' => $article_date, 710 'domain' => $this->domain); 711 $data = array('status' => 'success', 'result' => $result); 712 return $data; 713 } 440 714 441 if (strlen($this->data) > 3) { 442 // prepare some data before getting contents 443 $this->title = $this->getTitle(); 444 $this->keywords = $this->getKeywords(); 445 $this->description = $this->getDescription(); 446 447 // get the contents 448 return $this->getElementsByTags(); 449 } else { 450 return false; 451 } 452 } 453 454 private function getTitle() { 455 $this->parseDom(); 456 457 $title = $this->xpath->query('//title')->item(0)->nodeValue; 458 459 return $title; 460 } 461 462 private function getKeywords() { 463 // Get the 'content' attribute value in a <meta name="keywords" ... /> 464 $matches = array(); 465 $max_count = get_option("expresscurate_max_tags", 3); 466 // Search for <meta name="keywords" content="keyword1, keword2" /> 467 preg_match('/<meta.*?name=("|\')keywords("|\').*?content=("|\')(.*?)("|\')/i', $this->data, $matches); 468 if (count($matches) > 4) { 469 return array_filter(explode(",", trim($matches[4]))); 470 } 471 472 // Order of attributes could be swapped around: <meta content="keyword1, keword2" name="keywords" /> 473 preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')keywords("|\')/i', $this->data, $matches); 474 if (count($matches) > 2) { 475 return array_filter(explode(",", trim($matches[2]))); 476 } 477 478 // No match 479 return null; 480 } 481 482 private function getDescription() { 483 // Get the 'content' attribute value in a <meta name="description" ... /> 484 $matches = array(); 485 486 // Search for <meta name="description" content="Buy my stuff" /> 487 preg_match('/<meta.*?name=("|\')description("|\').*?content=("|\')(.*?)("|\')/i', $this->data, $matches); 488 if (count($matches) > 4) { 489 return $matches[4]; 490 } 491 492 // Order of attributes could be swapped around: <meta content="Buy my stuff" name="description" /> 493 preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')description("|\')/i', $this->data, $matches); 494 if (count($matches) > 2) { 495 return $matches[2]; 496 } 497 498 // No match 499 return null; 500 } 501 502 private function getElementsByTags() { 503 $this->parseDom(); 504 505 // TODO make sure this cleanup can be done earlier or later, or maybe shall not affect the base dom with original html at all 506 507 $result_images = array(); 508 $result_paragraphs = array(); 509 $result_h1 = ''; 510 $result_h2 = ''; 511 $result_h3 = ''; 512 513 // TODO this is a new xpath with the new modified dom, not sure if this is required if dom is passed with a reference 514 $imgTags = $this->xpath->query("//img"); 515 $i = 0; 516 foreach ($imgTags as $t) { 517 $src = $t->getAttribute('src'); 518 if (strlen($src) > 3) { 519 if (strpos($src, 'http://') !== false || strpos($src, 'https://') !== false) { 520 $src = $src; 521 } else if (strpos($src, '//') === 0) { 522 if(isset($this->fragment)) { 523 $src = $this->fragment . $src; 524 } 525 else{ 526 $src = $this->protocol . ":" . $src; 527 } 528 } elseif (strpos($src, '/') === 0) { 529 $src = $this->domain . $src; 530 } else { 531 $src = $this->path . $src; 532 } 533 534 $src = preg_replace('%([^:])([/]{2,})%', '\\1/', $src); 535 536 if (!in_array($src, $result_images)) { 537 $result_images[] = ($src); 538 } 539 $i++; 540 } 541 $t->parentNode->removeChild($t); 542 } 543 //get H1 544 $h1Tag = $this->xpath->query('//h1'); 545 foreach ($h1Tag as $h1) { 546 if (strlen($h1->nodeValue) > 3) { 547 $result_h1 .= $h1->nodeValue . "\n"; 548 } 549 $h1->parentNode->removeChild($h1); 550 } 551 //get H2 552 $h2Tag = $this->xpath->query('//h2'); 553 foreach ($h2Tag as $h2) { 554 if (strlen($h2->nodeValue) > 3) { 555 $result_h2 .= $h2->nodeValue . "\n"; 556 } 557 $h2->parentNode->removeChild($h2); 558 } 559 //get H3 560 $h3Tag = $this->xpath->query('//h3'); 561 foreach ($h3Tag as $h3) { 562 if (strlen($h3->nodeValue) > 3) { 563 $result_h3 .= $h3->nodeValue . "\n"; 564 } 565 $h3->parentNode->removeChild($h3); 566 } 567 //get text 568 $i = 0; 569 $articleTags = $this->xpath->query('/html/body/article'); 570 foreach ($articleTags as $t) { 571 $result_paragraphs[$i]['value'] = strip_tags(trim($t->nodeValue)); 572 $result_paragraphs[$i]['tag'] = 'article'; 573 $t->parentNode->removeChild($t); 574 $i++; 575 } 576 577 578 $textTags = $this->xpath->query('/html/body//text()'); 579 580 foreach ($textTags as $t) { 581 if ($t->length > 15 && $t->parentNode->tagName != 'a' && $t->parentNode->tagName != 'h1' && $t->parentNode->tagName != 'h2' && $t->parentNode->tagName != 'h3') { 582 if ($t->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->parentNode->nodeName == "blockquote") { 583 if ($t->parentNode->nodeName == "blockquote") { 584 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->nodeValue); 585 } elseif ($t->parentNode->parentNode && $t->parentNode->parentNode->nodeName == "blockquote") { 586 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->nodeValue); 587 } elseif ($t->parentNode->parentNode->parentNode && $t->parentNode->parentNode->parentNode->nodeName == "blockquote") { 588 $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->parentNode->nodeValue); 589 } 590 $result_paragraphs[$i]['tag'] = "blockquote"; 591 } else { 592 $result_paragraphs[$i]['value'] = strip_tags($t->nodeValue); 593 $result_paragraphs[$i]['tag'] = $t->parentNode->nodeName; 594 } 595 $i++; 596 } 597 } 598 //author 599 $article_author = ''; 600 $author = $this->xpath->query('//*[@rel="author"][1]')->item(0); 601 if ($author) { 602 $article_author = $author->nodeValue; 603 } 604 //date 605 $article_date = ''; 606 $date = $this->xpath->query('//*[@datetime][1]')->item(0); 607 if ($date) { 608 $article_date = $date->nodeValue; 609 } 610 611 612 //smart tags 613 $max_count = get_option("expresscurate_max_tags", 3); 614 $smart_tags = array(); 615 616 $defined_tags = get_option("expresscurate_defined_tags", ''); 617 if ($defined_tags) { 618 $defined_tags = explode(",", $defined_tags); 619 foreach ($defined_tags as $tag) { 620 $tag = trim($tag); 621 $count = $this->countMatches($tag); 622 if ($count > 0) { 623 $smart_tags[$tag] = $count; 624 } 625 } 626 } 627 628 if (count($this->keywords)) { 629 foreach ($this->keywords as $key => $keyword) { 630 $count = $this->countMatches($key); 631 if ($count > 0) { 632 $smart_tags[$keyword] = $count; 633 } 634 } 635 } 636 637 if (count($smart_tags) > 0) { 638 arsort($smart_tags); 639 $smart_tags = array_slice(array_keys(array_reverse($smart_tags)), 0, $max_count); 640 } 641 642 $result_paragraphs_unique = $this->arrayUnique($result_paragraphs); 643 $media = $this->containsMedia(); 644 645 $result = array( 646 'title' => $this->title, 647 'headings' => array('h1' => $result_h1, 'h2' => $result_h2, 'h3' => $result_h3), 648 'metas' => array('description' => $this->description, 'keywords' => $smart_tags), 649 'images' => $result_images, 650 'media' => $media, 651 'paragraphs' => $result_paragraphs_unique, 652 'author' => $article_author, 653 'date' => $article_date, 654 'domain' => $this->domain); 655 $data = array('status' => 'success', 'result' => $result); 656 return $data; 657 } 658 659 private function countMatches($keyword) { 660 $total_occurrence = 0; 661 $tag_in_title = array(); 662 $tag_in_content = array(); 663 preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->title, $tag_in_title); 664 preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->data, $tag_in_content); 665 $total_occurrence = count($tag_in_title[0]) + count($tag_in_content[0]); 666 return $total_occurrence; 667 } 668 669 private function arrayUnique($array, $preserveKeys = false) { 670 // Unique Array for return 671 $arrayRewrite = array(); 672 // Array with the md5 hashes 673 $arrayHashes = array(); 674 foreach ($array as $key => $item) { 675 // Serialize the current element and create a md5 hash 676 $hash = md5(serialize($item)); 677 // If the md5 didn't come up yet, add the element to 678 // to arrayRewrite, otherwise drop it 679 if (!isset($arrayHashes[$hash])) { 680 // Save the current element hash 681 $arrayHashes[$hash] = $hash; 682 // Add element to the unique Array 683 if ($preserveKeys) { 684 $arrayRewrite[$key] = $item; 685 } else { 686 $arrayRewrite[] = $item; 687 } 688 } 689 } 690 return $arrayRewrite; 691 } 692 693 public function analyzeKeywords() { 694 $keywordsString = get_option('expresscurate_defined_tags'); 695 $blogKeywords = !empty($keywordsString) ? explode(', ', $keywordsString) : array(); 696 697 $this->download(); 698 $this->parseDom(); 699 $this->parseArticle(); 700 701 $title = $this->dom->getElementsByTagName('h1')->item(0)->nodeValue; 702 $titleArray = preg_split('/\s+/u', $title); 703 704 $article = strip_tags($this->article->nodeValue); 705 $articleFiltered = preg_replace('/\b(a|able|about|above|abroad|according|accordingly|across|actually|adj|after|afterwards|again|against|ago|ahead|ain\'t|all|allow|allows|almost|alone|along|alongside|already|also|although|always|am|amid|amidst|among|amongst|an|and|another|any|anybody|anyhow|anyone|anything|anyway|anyways|anywhere|apart|appear|appreciate|appropriate|are|aren\'t|around|as|a\'s|aside|ask|asking|associated|at|available|away|awfully|b|back|backward|backwards|be|became|because|become|becomes|becoming|been|before|beforehand|begin|behind|being|believe|below|beside|besides|best|better|between|beyond|both|brief|but|by|c|came|can|cannot|cant|can\'t|caption|cause|causes|certain|certainly|changes|clearly|c\'mon|co|co.|com|come|comes|concerning|consequently|consider|considering|contain|containing|contains|corresponding|could|couldn\'t|course|c\'s|currently|d|dare|daren\'t|definitely|described|despite|did|didn\'t|different|directly|do|does|doesn\'t|doing|done|don\'t|down|downwards|during|e|each|edu|eg|eight|eighty|either|else|elsewhere|end|ending|enough|entirely|especially|et|etc|even|ever|evermore|every|everybody|everyone|everything|everywhere|ex|exactly|example|except|f|fairly|far|farther|few|fewer|fifth|first|five|followed|following|follows|for|forever|former|formerly|forth|forward|found|four|from|further|furthermore|g|get|gets|getting|given|gives|go|goes|going|gone|got|gotten|greetings|h|had|hadn\'t|half|happens|hardly|has|hasn\'t|have|haven\'t|having|he|he\'d|he\'ll|hello|help|hence|her|here|hereafter|hereby|herein|here\'s|hereupon|hers|herself|he\'s|hi|him|himself|his|hither|hopefully|how|howbeit|however|hundred|i|i\'d|ie|if|ignored|i\'ll|i\'m|immediate|in|inasmuch|inc|inc.|indeed|indicate|indicated|indicates|inner|inside|insofar|instead|into|inward|is|isn\'t|it|it\'d|it\'ll|its|it\'s|itself|i\'ve|j|just|k|keep|keeps|kept|know|known|knows|l|last|lately|later|latter|latterly|least|less|lest|let|let\'s|like|liked|likely|likewise|little|look|looking|looks|low|lower|ltd|m|made|mainly|make|makes|many|may|maybe|mayn\'t|me|mean|meantime|meanwhile|merely|might|mightn\'t|mine|minus|miss|more|moreover|most|mostly|mr|mrs|much|must|mustn\'t|my|myself|n|name|namely|nd|near|nearly|necessary|need|needn\'t|needs|neither|never|neverf|neverless|nevertheless|new|next|nine|ninety|no|nobody|non|none|nonetheless|noone|no-one|nor|normally|not|nothing|notwithstanding|novel|now|nowhere|o|obviously|of|off|often|oh|ok|okay|old|on|once|one|ones|one\'s|only|onto|opposite|or|other|others|otherwise|ought|oughtn\'t|our|ours|ourselves|out|outside|over|overall|own|p|particular|particularly|past|per|perhaps|placed|please|plus|possible|presumably|probably|provided|provides|q|que|quite|qv|r|rather|rd|re|really|reasonably|recent|recently|regarding|regardless|regards|relatively|respectively|right|round|s|said|same|saw|say|saying|says|second|secondly|see|seeing|seem|seemed|seeming|seems|seen|self|selves|sensible|sent|serious|seriously|seven|several|shall|shan\'t|she|she\'d|she\'ll|she\'s|should|shouldn\'t|since|six|so|some|somebody|someday|somehow|someone|something|sometime|sometimes|somewhat|somewhere|soon|sorry|specified|specify|specifying|still|sub|such|sup|sure|t|take|taken|taking|tell|tends|th|than|thank|thanks|thanx|that|that\'ll|thats|that\'s|that\'ve|the|their|theirs|them|themselves|then|thence|there|thereafter|thereby|there\'d|therefore|therein|there\'ll|there\'re|theres|there\'s|thereupon|there\'ve|these|they|they\'d|they\'ll|they\'re|they\'ve|thing|things|think|third|thirty|this|thorough|thoroughly|those|though|three|through|throughout|thru|thus|till|to|together|too|took|toward|towards|tried|tries|truly|try|trying|t\'s|twice|two|u|un|under|underneath|undoing|unfortunately|unless|unlike|unlikely|until|unto|up|upon|upwards|us|use|used|useful|uses|using|usually|v|value|various|versus|very|via|viz|vs|w|want|wants|was|wasn\'t|way|we|we\'d|welcome|well|we\'ll|went|were|we\'re|weren\'t|we\'ve|what|whatever|what\'ll|what\'s|what\'ve|when|whence|whenever|where|whereafter|whereas|whereby|wherein|where\'s|whereupon|wherever|whether|which|whichever|while|whilst|whither|who|who\'d|whoever|whole|who\'ll|whom|whomever|who\'s|whose|why|will|willing|wish|with|within|without|wonder|won\'t|would|wouldn\'t|x|y|yes|yet|you|you\'d|you\'ll|your|you\'re|yours|yourself|yourselves|you\'ve|z|zero, replacement)\\b/','', $article); 706 $articleFiltered = preg_replace('/\p{P}+/u',' ',$articleFiltered); 707 $articleArray = preg_split('/\s+/u', $articleFiltered); 708 $articleWordsCount = count($articleArray); 709 710 $result = array(); 711 712 foreach($blogKeywords as $keyword) { 713 $count = 0; 714 $inTitle = 'No'; 715 716 if (in_array(mb_strtolower($keyword), $articleArray)) { 717 $count++; 718 } 719 foreach($titleArray as $titleWord) { 720 if (mb_strtolower($titleWord) == mb_strtolower($keyword)) { 721 $inTitle = 'Yes'; 722 break; 723 } 724 } 725 if($count !== 0) { 726 $result[$keyword] = array('percent' => round($count/$articleWordsCount, 4), 'title' => $inTitle); 727 } 728 } 729 730 return $result; 731 } 732 733 public function containsMedia() { 734 $this->parseDom(); 735 736 $imgTags = $this->xpath->query("//img"); 737 $img_array = array(); 738 foreach ($imgTags as $t) { 739 $src = $t->getAttribute('src'); 740 $img_array[] = $src; 741 } 742 $obj = $this->xpath->query("//node()[(name()='iframe' or name()='video' or name()='source' or name()= 'object' or name()='embed') and (contains(@src,'youtube.com') or contains(@src ,'vimeo.com') or contains(@src,'youtu.be'))]"); 743 $videoArrays = array(); 744 foreach($obj as $objs) { 745 array_push($videoArrays,$objs->getAttribute('src')); 746 } 747 $mediaTags = array("images"=>count($img_array),"videos"=>count($videoArrays)); 748 return $mediaTags; 749 } 715 private function cloneElements() 716 { 717 $this->parseDom(); 718 $this->parseArticle(); 719 720 // TODO make sure this cleanup can be done earlier or later, or maybe shall not affect the base dom with original html at all 721 722 $result_images = array(); 723 $imgTags = $this->xpath->query(".//img", $this->article); 724 $i = 0; 725 foreach ($imgTags as $t) { 726 $src = $t->getAttribute('src'); 727 if (strlen($src) > 3) { 728 if (strpos($src, 'http://') !== false || strpos($src, 'https://') !== false) { 729 $src = $src; 730 } else if (strpos($src, '//') === 0) { 731 if (isset($this->fragment)) { 732 $src = $this->fragment . $src; 733 } else { 734 $src = $this->protocol . ":" . $src; 735 } 736 } elseif (strpos($src, '/') === 0) { 737 $src = $this->domain . $src; 738 } else { 739 $src = $this->path . $src; 740 } 741 742 $src = preg_replace('%([^:])([/]{2,})%', '\\1/', $src); 743 744 if (!in_array($src, $result_images)) { 745 $result_images[] = ($src); 746 } 747 $i++; 748 } 749 $t->parentNode->removeChild($t); 750 } 751 752 //smart tags 753 $max_count = get_option("expresscurate_max_tags", 3); 754 $smart_tags = array(); 755 756 $defined_tags = get_option("expresscurate_defined_tags", ''); 757 if ($defined_tags) { 758 $defined_tags = explode(",", $defined_tags); 759 foreach ($defined_tags as $tag) { 760 $tag = trim($tag); 761 $count = $this->countMatches($tag); 762 if ($count > 0) { 763 $smart_tags[$tag] = $count; 764 } 765 } 766 } 767 768 if (count($this->keywords)) { 769 foreach ($this->keywords as $key => $keyword) { 770 $count = $this->countMatches($key); 771 if ($count > 0) { 772 $smart_tags[$keyword] = $count; 773 } 774 } 775 } 776 777 if (count($smart_tags) > 0) { 778 arsort($smart_tags); 779 $smart_tags = array_slice(array_keys(array_reverse($smart_tags)), 0, $max_count); 780 } 781 782 $comments = $this->xpath->query(".//comment()",$this->article); 783 foreach($comments as $cmnt){ 784 $cmnt->parentNode->removeChild($cmnt); 785 } 786 $h1Tag = $this->xpath->query(".//h1",$this->article); 787 foreach ($h1Tag as $h1) { 788 $h1->parentNode->removeChild($h1); 789 } 790 $input = $this->xpath->query(".//node()[name()='iframe' or name()='input' or name()='button' or name='textarea' or name()='form']",$this->article); 791 foreach ($input as $inp) { 792 $inp->parentNode->removeChild($inp); 793 } 794 795 796 $articleContent = $this->dom->saveXML($this->article); 797 $result = array( 798 'title' => $this->title, 799 'content'=> $articleContent, 800 'metas' => array('keywords' => $smart_tags), 801 'images' => $result_images, 802 'domain' => $this->domain); 803 $data = array('status' => 'success', 'result' => $result); 804 return $data; 805 } 806 807 private function countMatches($keyword) 808 { 809 $total_occurrence = 0; 810 $tag_in_title = array(); 811 $tag_in_content = array(); 812 preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->title, $tag_in_title); 813 preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->data, $tag_in_content); 814 $total_occurrence = count($tag_in_title[0]) + count($tag_in_content[0]); 815 return $total_occurrence; 816 } 817 818 private function arrayUnique($array, $preserveKeys = false) 819 { 820 // Unique Array for return 821 $arrayRewrite = array(); 822 // Array with the md5 hashes 823 $arrayHashes = array(); 824 foreach ($array as $key => $item) { 825 // Serialize the current element and create a md5 hash 826 $hash = md5(serialize($item)); 827 // If the md5 didn't come up yet, add the element to 828 // to arrayRewrite, otherwise drop it 829 if (!isset($arrayHashes[$hash])) { 830 // Save the current element hash 831 $arrayHashes[$hash] = $hash; 832 // Add element to the unique Array 833 if ($preserveKeys) { 834 $arrayRewrite[$key] = $item; 835 } else { 836 $arrayRewrite[] = $item; 837 } 838 } 839 } 840 return $arrayRewrite; 841 } 842 843 public function analyzeKeywords() 844 { 845 $keywordsString = get_option('expresscurate_defined_tags'); 846 $blogKeywords = !empty($keywordsString) ? explode(', ', $keywordsString) : array(); 847 848 $this->download(); 849 $this->parseDom(); 850 $this->parseArticle(); 851 852 $title = $this->dom->getElementsByTagName('h1')->item(0)->nodeValue; 853 $titleArray = preg_split('/\s+/u', $title); 854 855 $article = strip_tags($this->article->nodeValue); 856 $articleFiltered = preg_replace('/\b(a|able|about|above|abroad|according|accordingly|across|actually|adj|after|afterwards|again|against|ago|ahead|ain\'t|all|allow|allows|almost|alone|along|alongside|already|also|although|always|am|amid|amidst|among|amongst|an|and|another|any|anybody|anyhow|anyone|anything|anyway|anyways|anywhere|apart|appear|appreciate|appropriate|are|aren\'t|around|as|a\'s|aside|ask|asking|associated|at|available|away|awfully|b|back|backward|backwards|be|became|because|become|becomes|becoming|been|before|beforehand|begin|behind|being|believe|below|beside|besides|best|better|between|beyond|both|brief|but|by|c|came|can|cannot|cant|can\'t|caption|cause|causes|certain|certainly|changes|clearly|c\'mon|co|co.|com|come|comes|concerning|consequently|consider|considering|contain|containing|contains|corresponding|could|couldn\'t|course|c\'s|currently|d|dare|daren\'t|definitely|described|despite|did|didn\'t|different|directly|do|does|doesn\'t|doing|done|don\'t|down|downwards|during|e|each|edu|eg|eight|eighty|either|else|elsewhere|end|ending|enough|entirely|especially|et|etc|even|ever|evermore|every|everybody|everyone|everything|everywhere|ex|exactly|example|except|f|fairly|far|farther|few|fewer|fifth|first|five|followed|following|follows|for|forever|former|formerly|forth|forward|found|four|from|further|furthermore|g|get|gets|getting|given|gives|go|goes|going|gone|got|gotten|greetings|h|had|hadn\'t|half|happens|hardly|has|hasn\'t|have|haven\'t|having|he|he\'d|he\'ll|hello|help|hence|her|here|hereafter|hereby|herein|here\'s|hereupon|hers|herself|he\'s|hi|him|himself|his|hither|hopefully|how|howbeit|however|hundred|i|i\'d|ie|if|ignored|i\'ll|i\'m|immediate|in|inasmuch|inc|inc.|indeed|indicate|indicated|indicates|inner|inside|insofar|instead|into|inward|is|isn\'t|it|it\'d|it\'ll|its|it\'s|itself|i\'ve|j|just|k|keep|keeps|kept|know|known|knows|l|last|lately|later|latter|latterly|least|less|lest|let|let\'s|like|liked|likely|likewise|little|look|looking|looks|low|lower|ltd|m|made|mainly|make|makes|many|may|maybe|mayn\'t|me|mean|meantime|meanwhile|merely|might|mightn\'t|mine|minus|miss|more|moreover|most|mostly|mr|mrs|much|must|mustn\'t|my|myself|n|name|namely|nd|near|nearly|necessary|need|needn\'t|needs|neither|never|neverf|neverless|nevertheless|new|next|nine|ninety|no|nobody|non|none|nonetheless|noone|no-one|nor|normally|not|nothing|notwithstanding|novel|now|nowhere|o|obviously|of|off|often|oh|ok|okay|old|on|once|one|ones|one\'s|only|onto|opposite|or|other|others|otherwise|ought|oughtn\'t|our|ours|ourselves|out|outside|over|overall|own|p|particular|particularly|past|per|perhaps|placed|please|plus|possible|presumably|probably|provided|provides|q|que|quite|qv|r|rather|rd|re|really|reasonably|recent|recently|regarding|regardless|regards|relatively|respectively|right|round|s|said|same|saw|say|saying|says|second|secondly|see|seeing|seem|seemed|seeming|seems|seen|self|selves|sensible|sent|serious|seriously|seven|several|shall|shan\'t|she|she\'d|she\'ll|she\'s|should|shouldn\'t|since|six|so|some|somebody|someday|somehow|someone|something|sometime|sometimes|somewhat|somewhere|soon|sorry|specified|specify|specifying|still|sub|such|sup|sure|t|take|taken|taking|tell|tends|th|than|thank|thanks|thanx|that|that\'ll|thats|that\'s|that\'ve|the|their|theirs|them|themselves|then|thence|there|thereafter|thereby|there\'d|therefore|therein|there\'ll|there\'re|theres|there\'s|thereupon|there\'ve|these|they|they\'d|they\'ll|they\'re|they\'ve|thing|things|think|third|thirty|this|thorough|thoroughly|those|though|three|through|throughout|thru|thus|till|to|together|too|took|toward|towards|tried|tries|truly|try|trying|t\'s|twice|two|u|un|under|underneath|undoing|unfortunately|unless|unlike|unlikely|until|unto|up|upon|upwards|us|use|used|useful|uses|using|usually|v|value|various|versus|very|via|viz|vs|w|want|wants|was|wasn\'t|way|we|we\'d|welcome|well|we\'ll|went|were|we\'re|weren\'t|we\'ve|what|whatever|what\'ll|what\'s|what\'ve|when|whence|whenever|where|whereafter|whereas|whereby|wherein|where\'s|whereupon|wherever|whether|which|whichever|while|whilst|whither|who|who\'d|whoever|whole|who\'ll|whom|whomever|who\'s|whose|why|will|willing|wish|with|within|without|wonder|won\'t|would|wouldn\'t|x|y|yes|yet|you|you\'d|you\'ll|your|you\'re|yours|yourself|yourselves|you\'ve|z|zero, replacement)\\b/', '', $article); 857 $articleFiltered = preg_replace('/\p{P}+/u', ' ', $articleFiltered); 858 $articleArray = preg_split('/\s+/u', $articleFiltered); 859 $articleWordsCount = count($articleArray); 860 861 $result = array(); 862 863 foreach ($blogKeywords as $keyword) { 864 $count = 0; 865 $inTitle = 'No'; 866 867 if (in_array(mb_strtolower($keyword), $articleArray)) { 868 $count++; 869 } 870 foreach ($titleArray as $titleWord) { 871 if (mb_strtolower($titleWord) == mb_strtolower($keyword)) { 872 $inTitle = 'Yes'; 873 break; 874 } 875 } 876 if ($count !== 0) { 877 $result[$keyword] = array('percent' => round($count / $articleWordsCount, 4), 'title' => $inTitle); 878 } 879 } 880 881 return $result; 882 } 883 884 public function containsMedia() 885 { 886 $this->parseDom(); 887 888 $imgTags = $this->xpath->query("//img"); 889 $img_array = array(); 890 foreach ($imgTags as $t) { 891 $src = $t->getAttribute('src'); 892 $img_array[] = $src; 893 } 894 $obj = $this->xpath->query("//node()[(name()='iframe' or name()='video' or name()='source' or name()= 'object' or name()='embed') and (contains(@src,'youtube.com') or contains(@src ,'vimeo.com') or contains(@src,'youtu.be'))]"); 895 $videoArrays = array(); 896 foreach ($obj as $objs) { 897 array_push($videoArrays, $objs->getAttribute('src')); 898 } 899 $mediaTags = array("images" => count($img_array), "videos" => count($videoArrays)); 900 return $mediaTags; 901 } 750 902 } 751 903 -
expresscurate/trunk/ExpressCurate_Keywords.php
r1129694 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 3 4 -
expresscurate/trunk/ExpressCurate_Sitemap.php
r1106118 r1137344 1 1 <?php 2 2 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 3 /** 4 * Created by PhpStorm. 5 * User: armen 6 * Date: 10/9/14 7 * Time: 2:39 PM 4 5 /* 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 8 10 */ 11 9 12 class ExpressCurate_Sitemap 10 13 { -
expresscurate/trunk/ExpressCurate_Tags.php
r1106118 r1137344 3 3 require_once(sprintf("%s/autoload.php", dirname(__FILE__))); 4 4 5 /* 6 Author: ExpressCurate 7 Author URI: http://www.expresscurate.com 8 License: GPLv3 or later 9 License URI: http://www.gnu.org/licenses/gpl.html 10 */ 11 5 12 class Expresscurate_Tags 6 13 { 7 8 14 private function checkOpenTag($matches) 9 15 { … … 47 53 return preg_replace($spans, '$1', $html); 48 54 } 49 50 51 55 } -
expresscurate/trunk/autoload.php
r1106118 r1137344 1 1 <?php 2 3 /* 4 Author: ExpressCurate 5 Author URI: http://www.expresscurate.com 6 License: GPLv3 or later 7 License URI: http://www.gnu.org/licenses/gpl.html 8 */ 9 2 10 function expresscurate_autoload($className) { 3 11 $classFile = sprintf("%s/$className", dirname(__FILE__)); -
expresscurate/trunk/css/dialog-style-3.9.css
r1106118 r1137344 1 div[aria-describedby="expresscurate_clone_dialog"], 1 2 div[aria-describedby="expresscurate_dialog"]{ 2 3 padding: 0 !important; … … 12 13 z-index: 100090; 13 14 } 15 div[aria-describedby="expresscurate_clone_dialog"] .ui-dialog-titlebar, 14 16 div[aria-describedby="expresscurate_dialog"] .ui-dialog-titlebar{ 15 17 padding: 0; … … 22 24 background-color: #222222; 23 25 } 26 div[aria-describedby="expresscurate_clone_dialog"] .ui-dialog-title, 24 27 div[aria-describedby="expresscurate_dialog"] .ui-dialog-title{ 25 28 display: block; … … 35 38 } 36 39 40 div[aria-describedby="expresscurate_clone_dialog"] .ui-button-icon-primary, 41 div[aria-describedby="expresscurate_clone_dialog"] .ui-dialog-titlebar-close span, 37 42 div[aria-describedby="expresscurate_dialog"] .ui-button-icon-primary, 38 43 div[aria-describedby="expresscurate_dialog"] .ui-dialog-titlebar-close span{ … … 40 45 } 41 46 47 div[aria-describedby="expresscurate_clone_dialog"] .ui-dialog-titlebar-close:before, 42 48 div[aria-describedby="expresscurate_dialog"] .ui-dialog-titlebar-close:before{ 43 49 line-height: 13px; 44 50 } 51 div[aria-describedby="expresscurate_clone_dialog"] .ui-button.ui-dialog-titlebar-close, 45 52 div[aria-describedby="expresscurate_dialog"] .ui-button.ui-dialog-titlebar-close{ 46 53 padding: 0; … … 53 60 margin: 0 !important; 54 61 } 62 div[aria-describedby="expresscurate_clone_dialog"] .ui-dialog-titlebar-close:before, 55 63 div[aria-describedby="expresscurate_dialog"] .ui-dialog-titlebar-close:before{ 56 64 line-height: 20px !important; … … 58 66 height: 30px !important; 59 67 } 68 div[aria-describedby="expresscurate_clone_dialog"] .ui-button.ui-dialog-titlebar-close:hover, 60 69 div[aria-describedby="expresscurate_dialog"] .ui-button.ui-dialog-titlebar-close:hover{ 61 70 color: #9d9d9d; 62 71 } 63 72 64 #expresscurate_dialog {73 .expresscurate_dialog { 65 74 padding: 0; 66 75 border:none; … … 76 85 display: none; 77 86 } 87 #expresscurate_dialog_content_clone_editor{ 88 height: 190px; 89 resize: none; 90 max-height: 190px; 91 overflow-y: scroll; 92 } -
expresscurate/trunk/css/expresscurate.css
r1129694 r1137344 801 801 color:#303030; 802 802 position: relative; 803 804 803 box-sizing: border-box; 805 804 -moz-box-sizing: border-box; … … 807 806 width: 100%; 808 807 } 808 .expresscurate_feedSettingsList li{ 809 line-height: 16px; 810 height: 45px; 811 } 812 809 813 .expresscurate_feedSettingsList li:hover, 810 814 .expresscurate_URL li:hover, … … 828 832 .expresscurate_feedSettingsList a{ 829 833 width: 65%; 834 margin-top: 5px; 835 font-family: OpenSans-Regular, Verdana, Geneva, sans-serif; 836 } 837 .expresscurate_feedSettingsList a small { 838 font-family: OpenSans-Light, Verdana, Geneva, sans-serif; 830 839 } 831 840 @media (max-width: 720px){ … … 852 861 width: 150px; 853 862 text-align: center; 863 margin-top: 2px; 854 864 } 855 865 .expresscurate_URL .rssStatus{ … … 1597 1607 } 1598 1608 1599 #expresscurate_dialog {1609 .expresscurate_dialog { 1600 1610 display: none; 1601 1611 } … … 1856 1866 } 1857 1867 1858 #expresscurate_dialog div.mce-toolbar-grp {1868 .expresscurate_dialog div.mce-toolbar-grp { 1859 1869 background-color: #dbdbdb !important; 1860 1870 } … … 1917 1927 } 1918 1928 .expresscurate_dialog .footer button.curate { 1919 margin-top: 10px;1920 1929 border: 1px solid #27cfae; 1921 1930 border-radius: 3px; … … 2616 2625 content: ' index'; 2617 2626 margin-left: 25px; 2627 } 2628 .expresscurate_advancedSEO_widget input[id="expresscurate_advanced_seo_post_copy"] +label:after{ 2629 content: ' no'; 2630 margin-left: 59px; 2631 } 2632 .expresscurate_advancedSEO_widget input[id="expresscurate_advanced_seo_post_copy"]:checked +label:after{ 2633 content: ' yes'; 2634 margin-left: 33px; 2618 2635 } 2619 2636 .expresscurate_advancedSEO_widget input[type="checkbox"]:checked+label{ … … 3554 3571 display: none; 3555 3572 right: 25px; 3573 margin-top: 9px; 3556 3574 } 3557 3575 .expresscurate_feed_dashboard .expresscurate_feedSettingsList li:hover .close{ … … 3690 3708 border: solid 1px #25bfa1; 3691 3709 } 3710 .expresscurate_controls .check.disabled{ 3711 background-position: -104px 6px; 3712 cursor: default; 3713 border: solid 1px #dddddd; 3714 } 3692 3715 .expresscurate_controls .check.active{ 3693 3716 background-position: -104px -75px; … … 3719 3742 background-position: -50px 8px; 3720 3743 } 3744 .expresscurate_feed_list .feedListControls .pull.disabled:hover, 3745 .expresscurate_feed_list .feedListControls .pull.disabled{ 3746 background: transparent !important; 3747 } 3721 3748 .expresscurate_feed_list .feedListControls .pull{ 3722 background-position: -144px 6px;3749 /*background-position: -144px 6px;*/ 3723 3750 background-size: auto 99px; 3724 3751 margin-right: 10px; 3725 3752 } 3753 .expresscurate_feed_list .feedListControls .pull .loading.expresscurate_startRotate{ 3754 background: url("../images/refresh.svg") no-repeat transparent center; 3755 height: 100%; 3756 width: 100%; 3757 display: block; 3758 -webkit-animation: rotate 1.2s infinite linear; 3759 -moz-animation: rotate 1.2s infinite linear; 3760 -o-animation: rotate 1.2s infinite linear; 3761 animation: rotate 1.2s infinite linear; 3762 } 3763 @-webkit-keyframes rotate{ 3764 from {-webkit-transform: rotate(0deg);} 3765 to {-webkit-transform: rotate(-359deg);} 3766 } 3767 @-moz-keyframes rotate{ 3768 from {-moz-transform: rotate(0deg);} 3769 to {-moz-transform: rotate(-359deg);} 3770 } 3771 @-o-keyframes rotate{ 3772 from {-o-transform: rotate(0deg);} 3773 to {-o-transform: rotate(-359deg);} 3774 } 3775 @keyframes rotate{ 3776 from {transform: rotate(0deg);} 3777 to {transform: rotate(-359deg);} 3778 } 3726 3779 .expresscurate_feed_list .feedListControls .pullTime{ 3727 3780 background-image: none; … … 3738 3791 -webkit-box-sizing: border-box; 3739 3792 cursor: default; 3793 border-color: #1cbb9f; 3740 3794 } 3741 3795 .expresscurate_feed_list .feedListControls .pullTime p{ … … 3749 3803 background: transparent; 3750 3804 cursor: default; 3805 border-color: #1cbb9f; 3751 3806 } 3752 3807 .expresscurate_controls .quotes.active:hover{ … … 3765 3820 border-color: #1cbb9f; 3766 3821 } 3767 .expresscurate_feed_list .feedListControls .pull .active:hover{3822 .expresscurate_feed_list .feedListControls .pull:hover{ 3768 3823 background-position: -144px -74px; 3769 3824 background-color: #1cbb9f; 3770 border-color: #1cbb9f;3771 3825 } 3772 3826 … … 3780 3834 background-position: -50px -25px; 3781 3835 } 3782 .expresscurate_feed_list .feedListControls .pull .active{3836 .expresscurate_feed_list .feedListControls .pull{ 3783 3837 background-position: -144px -33px; 3838 border-color: #1cbb9f; 3784 3839 } 3785 3840 … … 4905 4960 display: block; 4906 4961 } 4907 #wp-expresscurate_content_editor-editor-container .mce-container.mce-edit-area { 4962 #wp-expresscurate_dialog_content_clone_editor-editor-container .mce-container.mce-edit-area , 4963 #wp-expresscurate_dialog_content_editor-editor-container .mce-container.mce-edit-area { 4908 4964 max-height: 140px; 4909 4965 overflow-y: auto; -
expresscurate/trunk/js/Dialog.js
r1129694 r1137344 100 100 if (index < count && !shortPar) { 101 101 generateTags(value); 102 tinyMCE.get('expresscurate_ content_editor').execCommand('mceInsertContent', false, "<p>" + value + "<p>");102 tinyMCE.get('expresscurate_dialog_content_editor').execCommand('mceInsertContent', false, "<p>" + value + "<p>"); 103 103 } 104 104 } … … 223 223 } 224 224 generateTags(paragraph); 225 tinyMCE.get('expresscurate_ content_editor').execCommand('mceInsertContent', false, paragraph);225 tinyMCE.get('expresscurate_dialog_content_editor').execCommand('mceInsertContent', false, paragraph); 226 226 } 227 227 … … 232 232 233 233 function clearExpresscurateForm() { 234 var $dialog = $('#expresscurate_dialog'); 234 var $dialog = $('#expresscurate_dialog'), 235 $imageCounter = $dialog.find('.imageCount'); 235 236 $dialog.find('div.error').remove(); 236 237 $dialog.find('div.updated').remove(); 237 238 $dialog.find('ul').html(''); 238 $("#expresscurate_content_editor").val(''); 239 $dialog.find('#curated_title').val(''); 240 $imageCounter.text('0/0'); 239 241 $('.content .img').attr('style', '').addClass("noimage"); 240 242 $('.controls').hide(); 241 243 $("#curated_paragraphs").empty(); 242 if (typeof(tinyMCE) === "object" && typeof(tinyMCE.execCommand) === "function" && tinyMCE.get('expresscurate_content_editor')) { 243 tinyMCE.get('expresscurate_content_editor').setContent(''); 244 if (typeof(tinyMCE) === "object" && typeof(tinyMCE.execCommand) === "function" && tinyMCE.get('expresscurate_dialog_content_editor')) { 245 tinyMCE.get('expresscurate_dialog_content_editor').setContent(''); 246 tinyMCE.get('expresscurate_dialog_content_clone_editor').setContent(''); 244 247 } 245 248 $('#expresscurate_source').focus(); … … 311 314 } 312 315 313 function submitExpresscurateForm() { 314 ExpressCurateUtils.track('/post/content-dialog/loadpage'); 315 316 function submitExpresscurateForm(clone) { 316 317 var $dialog = $('#expresscurate_dialog'); 317 318 //remove autoComplete … … 323 324 var errorHTML = '', 324 325 notifHTML = '', 325 $url = $('#expresscurate_post_form').find('input');326 $url = clone ? $('#expresscurate_post_form').find('#expresscurate_clone_source') : $('#expresscurate_post_form').find('#expresscurate_source'); 326 327 $.ajax({ 327 328 type: 'POST', … … 340 341 data: $url.serialize() 341 342 }).done(function (res) { 342 343 var data = $.parseJSON(res); 344 if (data) { 345 if (data.status === 'error') { 346 errorHTML = '<div class="error">' + data.error + '</div>'; 343 var data = $.parseJSON(res); 344 if (data) { 345 if (data.status === 'error') { 346 errorHTML = '<div class="error">' + data.error + '</div>'; 347 $('#expresscurate_post_form').before(errorHTML); 348 $("#expresscurate_loading").fadeOut('fast'); 349 } else if (data.status === 'success') { 350 clearExpresscurateForm(); 351 if (data.result.title && data.result.title.length > 0) { 352 $("#curated_title").val(data.result.title); 353 } 354 if (data.result.images.length > 0) { 355 errorHTML = exportAPICheckImages(data.result.images); 356 } else { 357 $("#expresscurate_loading").fadeOut('fast'); 358 } 359 keywords = data.result.metas.keywords; 360 if (data.result.metas.keywords && data.result.metas.keywords.length > 0) { 361 displayCuratedTags(data.result.metas.keywords); 362 } 363 if (clone) { 364 if (data.result.paragraphs.length > 0) { 365 tinyMCE.get('expresscurate_dialog_content_clone_editor').execCommand('mceInsertContent', false, data.result.content); 366 } 367 ExpressCurateUtils.track('/post/content-dialog/clonepage'); 368 } else { 369 $(".controls").show(); 370 displaySpecials(data.result); 371 if (data.result.paragraphs.length > 0) { 372 $curatedParagraphs = data.result.paragraphs; 373 displayCuratedParagraphs(data.result.paragraphs, $("#expresscurate_autosummary").val(), false); 374 } 375 ExpressCurateUtils.track('/post/content-dialog/loadpage'); 376 } 377 $('#expresscurate_source').focus(); 378 } 379 } 380 else { 381 errorHTML = '<div class="error">Can\'t curate from this page</div>'; 347 382 $('#expresscurate_post_form').before(errorHTML); 348 383 $("#expresscurate_loading").fadeOut('fast'); 349 } else if (data.status === 'success') { 350 clearExpresscurateForm(); 351 $(".controls").show(); 352 if (data.result.title && data.result.title.length > 0) { 353 $("#curated_title").val(data.result.title); 354 } 355 if (data.result.images.length > 0) { 356 errorHTML = exportAPICheckImages(data.result.images); 357 } else { 358 $("#expresscurate_loading").fadeOut('fast'); 359 } 360 if (data.result.metas.keywords && data.result.metas.keywords.length > 0) { 361 displayCuratedTags(data.result.metas.keywords); 362 } 363 keywords = data.result.metas.keywords; 364 displaySpecials(data.result); 365 366 if (data.result.paragraphs.length > 0) { 367 $curatedParagraphs = data.result.paragraphs; 368 displayCuratedParagraphs(data.result.paragraphs, $("#expresscurate_autosummary").val(), false); 369 } 370 $('#expresscurate_source').focus(); 371 } 372 } else { 373 errorHTML = '<div class="error">Can\'t curate from this page</div>'; 374 $('#expresscurate_post_form').before(errorHTML); 375 $("#expresscurate_loading").fadeOut('fast'); 376 } 377 378 }); 384 } 385 386 } 387 ); 379 388 } 380 389 … … 402 411 }); 403 412 $dialog.on('click', function (e) { 404 if (!$(e.target).is('.autoComplete li')){413 if (!$(e.target).is('.autoComplete li')) { 405 414 $dialog.find('.autoComplete').remove(); 406 415 } … … 482 491 } 483 492 484 $("#expresscurate_ content_editor").addClass("mceEditor");493 $("#expresscurate_dialog_content_editor").addClass("mceEditor"); 485 494 486 495 var currentImage = 0; … … 523 532 openDialog(); 524 533 }); 525 $("#expresscurate_insert").click(function () { 526 var ed = tinyMCE.activeEditor, 534 $("#expresscurate_open-modal-clone").click(function (event) { 535 event.preventDefault(); 536 openDialog(false, true); 537 }); 538 $dialog.on('click', '#expresscurate_insert , #expresscurate_cloneInsert', function () { 539 var clone = $(this).is('#expresscurate_cloneInsert') ? true : false, 540 ed = tinyMCE.activeEditor, 527 541 highlightedElems = $(ed.getBody()).find('span.expresscurate_keywordsHighlight'); 542 if (clone) { 543 ExpressCurateUtils.track('/post/content-dialog/cloneintopost', true); 544 } else { 545 ExpressCurateUtils.track('/post/content-dialog/curateintopost', true); 546 } 528 547 if (highlightedElems.length > 0) { 529 548 highlightedElems.each(function (index, val) { … … 543 562 ExpressCurateSourceCollection.addNew(); 544 563 var html = "", 545 insiteHTML = '',546 564 bg = $('.img').css('background-image'); 547 565 … … 550 568 html += '<img class="' + alignImg + ' ' + imgSize + '" src="' + bg + '" data-img-curated-from="' + sourceVal + '">' 551 569 } 552 if (tinyMCE.get('expresscurate_content_editor').getContent().length > 0) { 553 html += '<blockquote cite = "' + sourceVal + '">' + tinyMCE.get('expresscurate_content_editor').getContent() + '<br />'; 554 } 555 html += insiteHTML; 570 571 if (clone) { 572 html += tinyMCE.get('expresscurate_dialog_content_clone_editor').getContent() + '<br />'; 573 } else { 574 html += '<blockquote cite = "' + sourceVal + '">' + tinyMCE.get('expresscurate_dialog_content_editor').getContent() + '<br />'; 575 } 576 556 577 if (html.length > 0) { 557 578 if (sourceVal.length > 0) { … … 562 583 var title = $("#curated_title").val(); 563 584 domain = domain.match(/^(http|https)/) ? domain : 'http://' + domain; 585 564 586 if (domain) { 565 html += '<footer><p class="expresscurate_source">' + $("#expresscurate_from").val() + ' <cite><a class="expresscurated" rel="nofollow" data-curated-url="' + domain + '" href = "' + domain + '">' + title + '</a></cite></p></footer><br/>'; 587 if (clone) { 588 html += '<footer><p class="expresscurate_source">Originally published at <cite><a class="expresscurated" rel="nofollow" data-cloned-url="' + 589 domain + '" href = "' + domain + 590 '"' + ($("#expresscurate_from_target").val() == 'on' ? ' target="_blank"' : '') + '>' + 591 title + '</a></cite></p></footer><br/>'; 592 } else { 593 html += '<footer><p class="expresscurate_source">' + $("#expresscurate_from").val() + 594 ' <cite><a class="expresscurated" rel="nofollow" data-curated-url="' + domain + '" href = "' + domain + 595 '"' + ($("#expresscurate_from_target").val() == 'on' ? ' target="_blank"' : '') + '>' + 596 title + '</a></cite></p></footer><br/>'; 597 } 566 598 } 567 599 } 568 html += '</blockquote><br />'; 600 601 if (clone) { 602 var $canonicalURL = $('#expresscurate_advanced_seo_canonical_url'), 603 $noFollow = $('#expresscurate_advanced_seo_nofollow'), 604 $noIndex = $('#expresscurate_advanced_seo_noindex'), 605 $copyCheck = $('#expresscurate_advanced_seo_post_copy'), 606 $copyCheckVal = $('#expresscurate_advanced_seo_post_copy_value'), 607 $noIndexVal = $('#expresscurate_advanced_seo_noindex_value'), 608 $noFollowVal = $('#expresscurate_advanced_seo_nofollow_value'), 609 $copyControlWrap = $('#expresscurate_ClonePostWrap'); 610 if ($canonicalURL.length) { 611 $copyControlWrap.removeClass('expresscurate_displayNone'); 612 $copyCheckVal.val('on'); 613 $canonicalURL.attr('value', domain).attr('readonly', true); 614 $noFollow.add($noIndex).attr('checked', false).attr('disabled', true); 615 $noFollowVal.add($noIndexVal).val('off'); 616 $copyCheck.attr('checked', true).attr('disabled', false); 617 } 618 } else { 619 html += '</blockquote><br />'; 620 } 569 621 var $title = $('#titlewrap').find('#title'); 570 622 if ($title.val().length === 0) { … … 577 629 return false; 578 630 } 579 ExpressCurateUtils.track('/post/content-dialog/curateintopost', true);580 631 }); 581 632 } … … 583 634 $('#expresscurate_submit').click(function () { 584 635 $("#expresscurate_loading").show(); 585 submitExpresscurateForm( );636 submitExpresscurateForm(false); 586 637 }); 587 638 $('#expresscurate_source').keypress(function (e) { 588 639 if (e.keyCode === 13 || e.keyCode === 40) { 589 640 $("#expresscurate_loading").show(); 590 submitExpresscurateForm(); 641 submitExpresscurateForm(false); 642 return false; 643 } 644 }); 645 $dialog.on('click', '#expresscurate_clone', function () { 646 $("#expresscurate_loading").show(); 647 submitExpresscurateForm(true); 648 }); 649 $('#expresscurate_clone_source').keypress(function (e) { 650 if (e.keyCode === 13 || e.keyCode === 40) { 651 $("#expresscurate_loading").show(); 652 submitExpresscurateForm(true); 591 653 return false; 592 654 } … … 666 728 } 667 729 668 function openDialog(source) { 669 var $dialog = $("#expresscurate_dialog"); 730 function openDialog(source, clone) { 731 var $dialog = $("#expresscurate_dialog"), 732 $load = $dialog.find('#expresscurate_submit'), 733 $clone = $dialog.find('#expresscurate_clone'), 734 $insert = $dialog.find('#expresscurate_insert'), 735 $insertClone = $dialog.find('#expresscurate_cloneInsert'), 736 $contenttextarea = $dialog.find('#expresscurate_dialog_content_editor_container'), 737 $cloneContentTextarea = $dialog.find('#expresscurate_dialog_content_clone_editor_container'), 738 $source = $dialog.find('#expresscurate_source'), 739 $cloneSource = $dialog.find('#expresscurate_clone_source'); 670 740 $dialog.dialog({ 671 741 'dialogClass': 'wp-dialog', … … 684 754 'close': clearExpresscurateForm 685 755 }); 756 if (clone) { 757 $load.add($insert).add($contenttextarea).add($source).addClass('expresscurate_displayNone'); 758 $clone.add($insertClone).add($cloneContentTextarea).add($cloneSource).removeClass('expresscurate_displayNone'); 759 tinyMCE.get('expresscurate_dialog_content_clone_editor').getBody().setAttribute('contenteditable', false); 760 ExpressCurateUtils.track('/post/content-dialog/startclone'); 761 } else { 762 $load.add($insert).add($contenttextarea).add($source).removeClass('expresscurate_displayNone'); 763 $clone.add($insertClone).add($cloneContentTextarea).add($cloneSource).addClass('expresscurate_displayNone'); 764 ExpressCurateUtils.track('/post/content-dialog/startcurate'); 765 } 686 766 $dialog.dialog('open'); 687 688 ExpressCurateUtils.track('/post/content-dialog/startcurate');689 767 } 690 768 … … 710 788 delCuratedTag: delCuratedTag 711 789 } 712 })(window.jQuery); 790 }) 791 (window.jQuery); 713 792 714 793 ExpresscurateDialog.setup(); -
expresscurate/trunk/js/Utils.js
r1129694 r1137344 19 19 message.addClass('expresscurate_displayNone'); 20 20 if (pageWithControls) { 21 $controls.removeClass('expresscurate_displayNone'); 21 $('.expresscurate_controls li.check').removeClass('disabled'); 22 //$('.expresscurate_controls li.layout').removeClass('expresscurate_displayNone'); 22 23 ExpressCurateBookmarks.fixedMenu(); 23 24 } … … 25 26 message.removeClass('expresscurate_displayNone'); 26 27 if (pageWithControls) { 27 $('.expresscurate_controls li.check').removeClass('active'); 28 $controls.addClass('expresscurate_displayNone'); 28 $controls.removeClass('active'); 29 //$('.expresscurate_controls li.layout').addClass('expresscurate_displayNone'); 30 $('.expresscurate_controls li.check').addClass('disabled'); 31 $('.expresscurate_controls li.pull').add($('.expresscurate_controls li.pullTime')).addClass('active'); 29 32 } 30 33 } -
expresscurate/trunk/js/feed/contentFeed.js
r1129694 r1137344 71 71 72 72 function pullFeedManualy() { 73 var $loading = $feedControls.find('.loading'), 74 $control = $('.feedListControls li.pull'); 75 $loading.addClass('expresscurate_startRotate'); 76 $control.addClass('disabled'); 73 77 $.ajax({ 74 78 type: 'POST', 75 79 url: 'admin-ajax.php?action=expresscurate_manual_pull_feed' 76 80 }).done(function (res) { 77 //console.log(res); 81 var data = $.parseJSON(res); 82 if (data) { 83 $.each(data.content, function (index, value) { 84 $("#expresscurate_feedBoxes").load("admin-ajax.php?action=expresscurate_show_content_feed_items #expresscurate_feedBoxes > li", function () { 85 $('.pullTime p').text('in ' + data.minutes_to_next_pull); 86 $masonryWrap.masonry('destroy').masonry({ 87 itemSelector: '.expresscurate_masonryItem', 88 isResizable: true, 89 isAnimated: true, 90 columnWidth: '.expresscurate_masonryItem', 91 gutter: 10 92 }); 93 ExpressCurateUtils.notDefinedMessage($notDefFeed, $feedBoxes.find(' > li')); 94 }); 95 }); 96 } 97 }).always(function () { 98 $loading.removeClass('expresscurate_startRotate'); 99 $control.removeClass('disabled'); 78 100 }); 79 101 } … … 114 136 }); 115 137 /*pull*/ 116 $('.expresscurate_feed_list .pull').on('click', function(){138 $('.expresscurate_feed_list .pull').on('click', function () { 117 139 pullFeedManualy(); 118 140 }); -
expresscurate/trunk/js/keywords/SEOControlCenter.js
r1129694 r1137344 120 120 $('html').on('click', function (e) { 121 121 if ($widgetWraper.length) { 122 var $suggestions =$widgetWraper.find('.suggestion li');122 var $suggestions = $widgetWraper.find('.suggestion li'); 123 123 if ($(e.target).is('.suggestion li')) { 124 124 var newKeyword = $(e.target).text(); … … 250 250 }); 251 251 $('#expresscurate_widget_wrapper .mark').on('click', function (e) { 252 ExpressCurateKeywords.markEditorKeywords();252 ExpressCurateKeywords.markEditorKeywords(); 253 253 }); 254 254 … … 269 269 } 270 270 }); 271 $('.expresscurate_moveToAdvanced').on('click',function(){ 271 $('#expresscurate_advanced_seo_post_copy').on('change', function () { 272 var $this = $(this), 273 $hiddenInput = $this.parent().find('input[type=hidden]'), 274 $canonicalURL = $('#expresscurate_advanced_seo_canonical_url'), 275 $noFollow = $('#expresscurate_advanced_seo_nofollow'), 276 $noIndex = $('#expresscurate_advanced_seo_noindex'); 277 if ($this.is(':checked')) { 278 $hiddenInput.val('on'); 279 $canonicalURL.attr('readonly',true); 280 $noFollow.add($noIndex).attr('disabled',true); 281 } else { 282 $hiddenInput.val('off'); 283 $canonicalURL.attr('readonly',false); 284 $noFollow.add($noIndex).attr('disabled',false); 285 } 286 }); 287 $('.expresscurate_moveToAdvanced').on('click', function () { 272 288 $('html, body').animate({ 273 289 scrollTop: $("#expresscurate_advanced_seo").offset().top - 40 -
expresscurate/trunk/js/sourceCollection.js
r1106118 r1137344 89 89 content = (($contentWrap.css("display") === "block") ? $contentWrap.val() : tinyMCE.get("content").getContent()), 90 90 /*find curated post's url*/ 91 myRegExp = new RegExp('((cite=)|(data-curated-url=) )["\']' + url + '["\' ]', 'gmi');91 myRegExp = new RegExp('((cite=)|(data-curated-url=)|(data-cloned-url=))["\']' + url + '["\' ]', 'gmi'); 92 92 93 93 if (content.match(myRegExp)) { -
expresscurate/trunk/readme.txt
r1129694 r1137344 5 5 Requires at least: 3.9 6 6 Tested up to: 4.1 7 Stable tag: 2.0.1 07 Stable tag: 2.0.11 8 8 License: GPLv3 or later 9 9 License URI: http://www.gnu.org/licenses/gpl.html … … 81 81 82 82 = How To Get Started = 83 [Download ExpressCurate plugin](http://downloads.wordpress.org/plugin/expresscurate.2.0.1 0.zip "Your favorite content marketing tools") for WordPress.83 [Download ExpressCurate plugin](http://downloads.wordpress.org/plugin/expresscurate.2.0.11.zip "Your favorite content marketing tools") for WordPress. 84 84 You can also [download](http://www.expresscurate.com/p/products/wordpress-theme "Your favorite WordPress Theme") a **free** [ExpressCurate WordPress theme](http://www.expresscurate.com/p/products/wordpress-theme "Your favorite WordPress Theme"). It will give your curated content a modern online news look. 85 85 … … 129 129 == Changelog == 130 130 131 = 2.0.11 = 132 * New Setting: Open Original Article Link in a New Window/Tab. 133 * Next Content Feed update time now available. 134 * Pull the Content Feed manually feature now available. 135 * Other miscellaneous bug fixes and improvements. 136 131 137 = 2.0.10 = 132 138 * Embed function: you can now embed Facebook, Twitter, YouTube, and Vimeo. Use the "Embed" button, paste the embed code and get the social post in your article. -
expresscurate/trunk/templates/advanced_seo_widget.php
r1129694 r1137344 2 2 global $post; 3 3 $sitemap = new ExpressCurate_Sitemap(); 4 $sitemapFrequencyArray =$sitemap->getSitemapFrequencyTagArray(); 4 $sitemapFrequencyArray = $sitemap->getSitemapFrequencyTagArray(); 5 6 $postCopy = (get_post_meta($post->ID, '_expresscurate_advanced_seo_post_copy', true) == 'on') ? true : false; 5 7 ?> 6 8 7 9 <div class="container expresscurate_Styles expresscurate_advancedSEO_widget"> 8 <input type="hidden" name="expresscurate_post_analysis_notification" value="0" id="expresscurate_post_analysis_notification"/> 9 <ul class="tabs"> 10 <li class="tab-link expresscurate_preventTextSelection green current" data-tab="tab-1">General</li> 11 <li class="tab-link expresscurate_preventTextSelection red <?php if(get_option('expresscurate_sitemap_update_permission') == 'error') echo 'disabled';?>" data-tab="tab-2">Sitemap</li> 12 <li class="tab-link expresscurate_preventTextSelection blue" data-tab="tab-3">Social</li> 13 <li class="tab-link postAnalysisLink expresscurate_preventTextSelection yellow" data-tab="tab-4">Post Analysis</li> 14 </ul> 15 16 <div id="tab-1" class="tab-content current"> 17 <a name="expresscurate" id="expresscurate" xmlns="http://www.w3.org/1999/html"></a> 18 19 <div id="expresscurate_advancedSEO_widget"> 20 <div class="info"> 21 <label for="expresscurate_advanced_seo_title" class="label">SEO Title</label> 22 </div> 23 <div class="value"> 24 <input id="expresscurate_advanced_seo_title" class="expresscurate_disableInputStyle" type="text" 25 name='expresscurate_advanced_seo_title' 26 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_title', true); ?>"> 27 </div> 28 <div class="expresscurate_clear"></div> 29 <div class="info"> 30 <label for="expresscurate_advanced_seo_canonical_url" class="label">Cannonical URL</label> 31 </div> 32 <div class="value"> 33 <input id="expresscurate_advanced_seo_canonical_url" class="expresscurate_disableInputStyle" type="text" 34 name='expresscurate_advanced_seo_canonical_url' 35 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_canonical_url', true); ?>"> 36 </div> 37 <div class="expresscurate_clear"></div> 38 <div class="info"> 39 <label class="robotsLabel">Robots must follow links </label> 40 </div> 41 <div class="value"> 42 <input class="expresscurate_displayNone" id="expresscurate_advanced_seo_nofollow" type='checkbox' 43 name='expresscurate_advanced_seo_nofollow' 44 <?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true) == 'on' || !get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true)) ? 'checked' : '' ?>> 45 <label class="expresscurate_preventTextSelection" for="expresscurate_advanced_seo_nofollow"></label> 46 <input type="hidden" id="expresscurate_advanced_seo_nofollow_value" name="expresscurate_advanced_seo_nofollow_value" value="<?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true))?get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true):"on"; ?>"> 47 </div> 48 <div class="expresscurate_clear"></div> 49 <div class="info"> 50 <label class="robotsLabel">Robots must index this page </label> 51 </div> 52 <div class="value"> 53 <input class="expresscurate_displayNone" id="expresscurate_advanced_seo_noindex" type='checkbox' 54 name='expresscurate_advanced_seo_noindex' 55 <?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true) == 'on' || !get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true)) ? 'checked' : '' ?>> 56 <label class="expresscurate_preventTextSelection" for="expresscurate_advanced_seo_noindex"></label> 57 <input type="hidden" id="expresscurate_advanced_seo_noindex_value" name="expresscurate_advanced_seo_noindex_value" value="<?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true))?get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true):"on"; ?>"> 58 </div> 59 <div class="expresscurate_clear"></div> 60 </div> 61 </div> 62 <div id="tab-2" class="tab-content"> 63 <div id="expresscurate_sitemap_widget"> 64 <ul class="expresscurate_sitemap_widget"> 65 <li> 10 <input type="hidden" name="expresscurate_post_analysis_notification" value="0" 11 id="expresscurate_post_analysis_notification"/> 12 <ul class="tabs"> 13 <li class="tab-link expresscurate_preventTextSelection green current" data-tab="tab-1">General</li> 14 <li class="tab-link expresscurate_preventTextSelection red <?php if (get_option('expresscurate_sitemap_update_permission') == 'error') echo 'disabled'; ?>" 15 data-tab="tab-2">Sitemap 16 </li> 17 <li class="tab-link expresscurate_preventTextSelection blue" data-tab="tab-3">Social</li> 18 <li class="tab-link postAnalysisLink expresscurate_preventTextSelection yellow" data-tab="tab-4">Post Analysis 19 </li> 20 </ul> 21 22 <div id="tab-1" class="tab-content current"> 23 <a name="expresscurate" id="expresscurate" xmlns="http://www.w3.org/1999/html"></a> 24 25 <div id="expresscurate_advancedSEO_widget"> 26 <div id="expresscurate_ClonePostWrap" class="<?php if(!$postCopy) {echo 'expresscurate_displayNone';} ?>"> 66 27 <div class="info"> 67 < span class="label">Configure Sitemap Manually</span>28 <label for="expresscurate_advanced_seo_canonical_url" class="label">Content cloned</label> 68 29 </div> 69 30 <div class="value"> 70 <input class="expresscurate_displayNone" type="checkbox" 71 id="expresscurate_sitemap_post_configure_manually" 72 name="expresscurate_sitemap_post_configure_manually" <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_configure_manually', true) == 'on') echo 'checked'; ?>> 73 <label for="expresscurate_sitemap_post_configure_manually"></label> 31 <input class="expresscurate_displayNone" id="expresscurate_advanced_seo_post_copy" 32 type='checkbox' <?php if(!$postCopy) { 33 echo 'disabled="disabled"'; 34 } ?> 35 name='expresscurate_advanced_seo_post_copy' 36 <?php echo ($postCopy) ? 'checked' : '' ?>> 37 <label class="expresscurate_preventTextSelection" for="expresscurate_advanced_seo_post_copy"></label> 38 <input type="hidden" id="expresscurate_advanced_seo_post_copy_value" 39 name="expresscurate_advanced_seo_post_copy_value" 40 value="<?php echo ($postCopy) ? "on" : "off"; ?>"> 74 41 </div> 75 <div class="expresscurate_clear"></div> 76 </li> 77 <li class="hiddenOptions <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_configure_manually', true) != 'on') echo 'expresscurate_displayNone'; ?>"> 78 <ul> 79 <li> 80 <div class="info"> 81 <span class="label">Exclude from sitemap</span> 82 </div> 83 <div class="value"> 84 <input class="expresscurate_displayNone" type="checkbox" 85 id="expresscurate_sitemap_post_exclude_from_sitemap" 86 name="expresscurate_sitemap_post_exclude_from_sitemap" <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_exclude_from_sitemap', true) == 'on') echo 'checked'; ?>> 87 <label for="expresscurate_sitemap_post_exclude_from_sitemap"></label> 88 </div> 89 <div class="expresscurate_clear"></div> 90 </li> 91 92 <ul class="sitemapOption <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_exclude_from_sitemap', true) == 'on') echo 'expresscurate_displayNone'; ?>"> 42 </div> 43 <div class="info"> 44 <label for="expresscurate_advanced_seo_title" class="label">SEO Title</label> 45 </div> 46 <div class="value"> 47 <input id="expresscurate_advanced_seo_title" class="expresscurate_disableInputStyle" type="text" 48 name='expresscurate_advanced_seo_title' 49 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_title', true); ?>"> 50 </div> 51 <div class="expresscurate_clear"></div> 52 <div class="info"> 53 <label for="expresscurate_advanced_seo_canonical_url" class="label">Canonical URL</label> 54 </div> 55 <div class="value"> 56 <input id="expresscurate_advanced_seo_canonical_url" class="expresscurate_disableInputStyle" type="text" 57 <?php if ($postCopy) { 58 echo 'readonly="true"'; 59 } ?> 60 name='expresscurate_advanced_seo_canonical_url' 61 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_canonical_url', true); ?>"> 62 </div> 63 <div class="expresscurate_clear"></div> 64 <div class="info"> 65 <label class="robotsLabel">Robots must follow links </label> 66 </div> 67 <div class="value"> 68 <input class="expresscurate_displayNone" id="expresscurate_advanced_seo_nofollow" type='checkbox' 69 <?php if ($postCopy) { 70 echo 'disabled="disabled"'; 71 } ?> 72 name='expresscurate_advanced_seo_nofollow' 73 <?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true) == 'on' || !get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true)) ? 'checked' : '' ?>> 74 <label class="expresscurate_preventTextSelection" for="expresscurate_advanced_seo_nofollow"></label> 75 <input type="hidden" id="expresscurate_advanced_seo_nofollow_value" 76 name="expresscurate_advanced_seo_nofollow_value" 77 value="<?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true)) ? get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true) : "on"; ?>"> 78 </div> 79 <div class="expresscurate_clear"></div> 80 <div class="info"> 81 <label class="robotsLabel">Robots must index this page </label> 82 </div> 83 <div class="value"> 84 <input class="expresscurate_displayNone" id="expresscurate_advanced_seo_noindex" type='checkbox' 85 <?php if ($postCopy) { 86 echo 'disabled="disabled"'; 87 } ?> 88 name='expresscurate_advanced_seo_noindex' 89 <?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true) == 'on' || !get_post_meta($post->ID, '_expresscurate_advanced_seo_nofollow', true)) ? 'checked' : '' ?>> 90 <label class="expresscurate_preventTextSelection" for="expresscurate_advanced_seo_noindex"></label> 91 <input type="hidden" id="expresscurate_advanced_seo_noindex_value" 92 name="expresscurate_advanced_seo_noindex_value" 93 value="<?php echo (get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true)) ? get_post_meta($post->ID, '_expresscurate_advanced_seo_noindex', true) : "on"; ?>"> 94 </div> 95 <div class="expresscurate_clear"></div> 96 </div> 97 </div> 98 <div id="tab-2" class="tab-content"> 99 <div id="expresscurate_sitemap_widget"> 100 <ul class="expresscurate_sitemap_widget"> 101 <li> 102 <div class="info"> 103 <span class="label">Configure Sitemap Manually</span> 104 </div> 105 <div class="value"> 106 <input class="expresscurate_displayNone" type="checkbox" 107 id="expresscurate_sitemap_post_configure_manually" 108 name="expresscurate_sitemap_post_configure_manually" <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_configure_manually', true) == 'on') echo 'checked'; ?>> 109 <label for="expresscurate_sitemap_post_configure_manually"></label> 110 </div> 111 <div class="expresscurate_clear"></div> 112 </li> 113 <li class="hiddenOptions <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_configure_manually', true) != 'on') echo 'expresscurate_displayNone'; ?>"> 114 <ul> 93 115 <li> 94 116 <div class="info"> 95 <span class="label">Sitemap frequency</span> 96 <span class="gray-italic desc">Please select frequency for posts in sitemap</span> 117 <span class="label">Exclude from sitemap</span> 97 118 </div> 98 119 <div class="value"> 99 <?php $expresscurate_sitemap_post_frequency = get_post_meta($post->ID, '_expresscurate_sitemap_post_frequency', true) ?> 100 <select name="expresscurate_sitemap_post_frequency" 101 id="expresscurate_sitemap_post_frequency"> 102 <?php foreach($sitemapFrequencyArray as $key=>$val) { 103 echo '<option value="' . $key . '"'; 104 if ($key == $expresscurate_sitemap_post_frequency) { 105 echo ' selected="selected"'; 106 } 107 echo '>' . $val . '</option>'; 108 }?> 109 </select> 120 <input class="expresscurate_displayNone" type="checkbox" 121 id="expresscurate_sitemap_post_exclude_from_sitemap" 122 name="expresscurate_sitemap_post_exclude_from_sitemap" <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_exclude_from_sitemap', true) == 'on') echo 'checked'; ?>> 123 <label for="expresscurate_sitemap_post_exclude_from_sitemap"></label> 110 124 </div> 111 125 <div class="expresscurate_clear"></div> 112 126 </li> 113 <li> 114 <div class="info"> 115 <span class="label">Sitemap priority</span> 116 <span class="gray-italic desc">Please select priority for posts in sitemap</span> 117 </div> 118 <div class="value"> 119 <?php $expresscurate_sitemap_post_priority = get_post_meta($post->ID, '_expresscurate_sitemap_post_priority', true) ?> 120 <select name="expresscurate_sitemap_post_priority" 121 id="expresscurate_sitemap_post_priority"> 122 <?php for($i=0.1; $i<=1; $i=$i+0.1) { 123 echo '<option value="'.$i.'"'; 124 if ($i == $expresscurate_sitemap_post_priority) { 125 echo ' selected="selected"'; 126 } 127 echo '>'.$i.'</option>'; 128 }?> 129 </select> 130 </div> 131 <div class="expresscurate_clear"></div> 132 </li> 127 128 <ul class="sitemapOption <?php if (get_post_meta($post->ID, '_expresscurate_sitemap_post_exclude_from_sitemap', true) == 'on') echo 'expresscurate_displayNone'; ?>"> 129 <li> 130 <div class="info"> 131 <span class="label">Sitemap frequency</span> 132 <span class="gray-italic desc">Please select frequency for posts in sitemap</span> 133 </div> 134 <div class="value"> 135 <?php $expresscurate_sitemap_post_frequency = get_post_meta($post->ID, '_expresscurate_sitemap_post_frequency', true) ?> 136 <select name="expresscurate_sitemap_post_frequency" 137 id="expresscurate_sitemap_post_frequency"> 138 <?php foreach ($sitemapFrequencyArray as $key => $val) { 139 echo '<option value="' . $key . '"'; 140 if ($key == $expresscurate_sitemap_post_frequency) { 141 echo ' selected="selected"'; 142 } 143 echo '>' . $val . '</option>'; 144 } ?> 145 </select> 146 </div> 147 <div class="expresscurate_clear"></div> 148 </li> 149 <li> 150 <div class="info"> 151 <span class="label">Sitemap priority</span> 152 <span class="gray-italic desc">Please select priority for posts in sitemap</span> 153 </div> 154 <div class="value"> 155 <?php $expresscurate_sitemap_post_priority = get_post_meta($post->ID, '_expresscurate_sitemap_post_priority', true) ?> 156 <select name="expresscurate_sitemap_post_priority" 157 id="expresscurate_sitemap_post_priority"> 158 <?php for ($i = 0.1; $i <= 1; $i = $i + 0.1) { 159 echo '<option value="' . $i . '"'; 160 if ($i == $expresscurate_sitemap_post_priority) { 161 echo ' selected="selected"'; 162 } 163 echo '>' . $i . '</option>'; 164 } ?> 165 </select> 166 </div> 167 <div class="expresscurate_clear"></div> 168 </li> 169 </ul> 133 170 </ul> 134 </ul> 135 </li> 136 </ul> 171 </li> 172 </ul> 173 </div> 174 </div> 175 <div id="tab-3" class="tab-content"> 176 <div id="expresscurate_social_widget"> 177 <div class="info"> 178 <label for="expresscurate_advanced_seo_social_title" class="label">Title</label> 179 </div> 180 <div class="value"> 181 <input id="expresscurate_advanced_seo_social_title" class="expresscurate_disableInputStyle" type="text" 182 name='expresscurate_advanced_seo_social_title' 183 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_title', true); ?>"> 184 </div> 185 <div class="expresscurate_clear"></div> 186 <div class="info"> 187 <label for="expresscurate_advanced_seo_social_shortdesc" class="label">Short Description</label> 188 </div> 189 <div class="value"> 190 <input id="expresscurate_advanced_seo_social_shortdesc" class="expresscurate_disableInputStyle" 191 type="text" 192 name='expresscurate_advanced_seo_social_shortdesc' 193 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_shortdesc', true); ?>"> 194 </div> 195 <div class="expresscurate_clear"></div> 196 <div class="info"> 197 <label for="expresscurate_advanced_seo_social_desc" class="label">Description</label> 198 </div> 199 <div class="value"> 200 <input id="expresscurate_advanced_seo_social_desc" class="expresscurate_disableInputStyle" type="text" 201 name='expresscurate_advanced_seo_social_desc' 202 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_desc', true); ?>"> 203 </div> 204 <div class="expresscurate_clear"></div> 205 </div> 206 </div> 207 <div id="tab-4" class="tab-content postAnalysisTab"> 208 137 209 </div> 138 210 </div> 139 <div id="tab-3" class="tab-content"> 140 <div id="expresscurate_social_widget"> 141 <div class="info"> 142 <label for="expresscurate_advanced_seo_social_title" class="label">Title</label> 143 </div> 144 <div class="value"> 145 <input id="expresscurate_advanced_seo_social_title" class="expresscurate_disableInputStyle" type="text" 146 name='expresscurate_advanced_seo_social_title' 147 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_title', true); ?>"> 148 </div> 149 <div class="expresscurate_clear"></div> 150 <div class="info"> 151 <label for="expresscurate_advanced_seo_social_shortdesc" class="label">Short Description</label> 152 </div> 153 <div class="value"> 154 <input id="expresscurate_advanced_seo_social_shortdesc" class="expresscurate_disableInputStyle" type="text" 155 name='expresscurate_advanced_seo_social_shortdesc' 156 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_shortdesc', true); ?>"> 157 </div> 158 <div class="expresscurate_clear"></div> 159 <div class="info"> 160 <label for="expresscurate_advanced_seo_social_desc" class="label">Description</label> 161 </div> 162 <div class="value"> 163 <input id="expresscurate_advanced_seo_social_desc" class="expresscurate_disableInputStyle" type="text" 164 name='expresscurate_advanced_seo_social_desc' 165 value="<?php echo get_post_meta($post->ID, '_expresscurate_advanced_seo_social_desc', true); ?>"> 166 </div> 167 <div class="expresscurate_clear"></div> 168 </div> 169 </div> 170 <div id="tab-4" class="tab-content postAnalysisTab"> 171 172 </div> 173 </div> 174 211 -
expresscurate/trunk/templates/bookmarks.php
r1129694 r1137344 12 12 } ?>"> 13 13 <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular"> 14 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>14 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 15 15 16 16 <h2>Bookmarks</h2> … … 21 21 </div> 22 22 <div class="controlsWrap"> 23 <ul class="bookmarkListControls expresscurate_preventTextSelection expresscurate_controls expresscurate_displayNone">23 <ul class="bookmarkListControls expresscurate_preventTextSelection expresscurate_controls"> 24 24 <li class="check"> 25 25 <span class="tooltip">select / deselect</span> -
expresscurate/trunk/templates/dashboard.php
r1129694 r1137344 20 20 <div class="expresscurate_blocks expresscurate_Styles wrap"> 21 21 <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular"> 22 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>22 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 23 23 24 24 <h2>ExpressCurate</h2> -
expresscurate/trunk/templates/dialog.php
r1129694 r1137344 1 1 <?php 2 2 $settings = array('wpautop' => false, 'media_buttons' => false, 'teeny' => true, 'tinymce' => true, 'quicktags' => false); 3 $settingsClone = array('wpautop' => false, 'media_buttons' => false, 'teeny' => true, 'tinymce' => true, 'quicktags' => false ); 3 4 ?> 4 5 <div> 5 <div class="content_editor expresscurate_Styles" id ="expresscurate_post_form"> 6 <div class="main"> 7 <div class="header"> 8 <div class="addressbar"> 9 <input type="text" placeholder="<?php echo __('Insert source URL to start', ExpressCurate_Actions::PLUGIN_FOLDER) ?>" id="expresscurate_source" name="expresscurate_source" value="<?php echo @get_post_meta($post->ID, 'expresscurate_source', true); ?>"> 10 <button class="load" id="expresscurate_submit">Load</button> 11 </div> 12 <div class="title"> 13 <input type="text" value="" id="curated_title"> 14 </div> 15 </div> 16 <div class="content"> 17 <div class="hidden"> 18 <ul id="curated_images"> 19 </ul> 20 </div> 21 <div class="left imgContainer"> 22 <div class="imgIcons"> 23 <div class="sizeX active"> 24 <div class="tooltipWrap"> 25 <span>Large size</span> 6 <div class="content_editor expresscurate_Styles" id="expresscurate_post_form"> 7 <div class="main"> 8 <div class="header"> 9 <div class="addressbar"> 10 <input type="text" class="expresscurate_load" 11 placeholder="<?php echo __('Insert source URL to start', ExpressCurate_Actions::PLUGIN_FOLDER) ?>" 12 id="expresscurate_source" name="expresscurate_source" 13 value="<?php echo @get_post_meta($post->ID, 'expresscurate_source', true); ?>"> 14 <input type="text" class="expresscurate_load" 15 placeholder="<?php echo __('Insert source URL to start', ExpressCurate_Actions::PLUGIN_FOLDER) ?>" 16 id="expresscurate_clone_source" name="expresscurate_source" 17 value="<?php echo @get_post_meta($post->ID, 'expresscurate_source', true); ?>"> 18 <button class="load" id="expresscurate_submit">Load</button> 19 <button class="load expresscurate_displayNone" id="expresscurate_clone">Clone</button> 20 </div> 21 <div class="title"> 22 <input type="text" value="" id="curated_title"> 23 </div> 24 </div> 25 <div class="content"> 26 <div class="hidden"> 27 <ul id="curated_images"> 28 </ul> 29 </div> 30 <div class="left imgContainer"> 31 <div class="imgIcons"> 32 <div class="sizeX active"> 33 <div class="tooltipWrap"> 34 <span>Large size</span> 35 </div> 36 </div> 37 <div class="sizeM"> 38 <div class="tooltipWrap"> 39 <span>Middle size</span> 40 </div> 41 </div> 42 <div class="sizeS"> 43 <div class="tooltipWrap"> 44 <span>Small size</span> 45 </div> 46 </div> 47 48 <div class="prevImg prev"> 49 <div class="tooltipWrap"> 50 <span>Previous</span> 51 </div> 52 </div> 53 <div class="nextImg next"> 54 <div class="tooltipWrap"> 55 <span>Next</span> 56 </div> 57 </div> 58 59 <div class="alignleft imgAlign"> 60 <div class="tooltipWrap"> 61 <span>Align left</span> 62 </div> 63 </div> 64 <div class="alignnone active imgAlign"> 65 <div class="tooltipWrap"> 66 <span>Fit to center</span> 67 </div> 68 </div> 69 <div class="alignright imgAlign"> 70 <div class="tooltipWrap"> 71 <span>Align right</span> 72 </div> 73 </div> 74 </div> 75 <div class="img noimage"> 76 <span class="imageCount expresscurate_displayNone"></span> 26 77 </div> 27 78 </div> 28 <div class=" sizeM">29 <div class="tooltipWrap">30 < span>Middle size</span>79 <div class="editor right"> 80 <div id="expresscurate_dialog_content_editor_container"> 81 <?php wp_editor('', 'expresscurate_dialog_content_editor', $settings); ?> 31 82 </div> 32 </div> 33 <div class="sizeS"> 34 <div class="tooltipWrap"> 35 <span>Small size</span> 83 <div id="expresscurate_dialog_content_clone_editor_container" class="expresscurate_displayNone"> 84 <?php wp_editor('', 'expresscurate_dialog_content_clone_editor', $settingsClone); ?> 36 85 </div> 37 </div> 38 39 <div class="prevImg prev"> 40 <div class="tooltipWrap"> 41 <span>Previous</span> 42 </div> 43 </div> 44 <div class="nextImg next"> 45 <div class="tooltipWrap"> 46 <span>Next</span> 47 </div> 48 </div> 49 50 <div class="alignleft imgAlign"> 51 <div class="tooltipWrap"> 52 <span>Align left</span> 53 </div> 54 </div> 55 <div class="alignnone active imgAlign"> 56 <div class="tooltipWrap"> 57 <span>Fit to center</span> 58 </div> 59 </div> 60 <div class="alignright imgAlign"> 61 <div class="tooltipWrap"> 62 <span>Align right</span> 63 </div> 86 <div class="clear"></div> 64 87 </div> 65 88 </div> 66 <div class="img noimage"> 67 <span class="imageCount expresscurate_displayNone"></span> 89 <div class="clear"></div> 90 <div class="controls hidden"> 91 <ul class="expresscurate_preventTextSelection tags" id="expresscurate_special"> 92 93 </ul> 94 <div class="clear"></div> 95 <div id="expresscurate_slider" class="slide_container"> 96 <div class="slider"> 97 <ul class="paragraphs_preview" id="curated_paragraphs"> 98 </ul> 99 </div> 100 <div class="prevSlide inactiveButton"></div> 101 <div class="nextSlide inactiveButton"></div> 102 </div> 103 <div class="clear"></div> 68 104 </div> 69 105 </div> 70 <div class="editor right"> 71 <?php wp_editor('', 'expresscurate_content_editor', $settings); ?> 72 73 <div class="clear"></div> 106 <div class="footer"> 107 <input type="hidden" value="<?php echo get_option('expresscurate_curated_text', 'Curated from'); ?>" 108 id="expresscurate_from" name="expresscurate_from"/> 109 <input type="hidden" value="<?php echo get_option('expresscurate_curated_link_target', 'on'); ?>" 110 id="expresscurate_from_target" name="expresscurate_from_target"/> 111 <input type="hidden" value="<?php echo get_option('expresscurate_autosummary', 5); ?>" 112 id="expresscurate_autosummary" name="expresscurate_autosummary"/> 113 <ul class="labels" id="curated_tags"> 114 <li class="markButton expresscurate_displayNone expresscurate_preventTextSelection"> 115 <span>mark keywords</span></li> 116 </ul> 117 <div class="clear"></div> 118 <button class="curate right" id="expresscurate_insert" 119 onclick="return false;"><?php echo __('Curate into post', ExpressCurate_Actions::PLUGIN_FOLDER) ?></button> 120 <button class="curate right expresscurate_displayNone" id="expresscurate_cloneInsert" 121 onclick="return false;"><?php echo __('Clone Post', ExpressCurate_Actions::PLUGIN_FOLDER) ?></button> 122 <div class="clear"></div> 74 123 </div> 75 </div>76 <div class="clear"></div>77 <div class="controls hidden">78 <ul class="expresscurate_preventTextSelection tags" id="expresscurate_special">79 80 </ul>81 <div class="clear"></div>82 <div id="expresscurate_slider" class="slide_container">83 <div class="slider">84 <ul class="paragraphs_preview" id="curated_paragraphs">85 </ul>86 </div>87 <div class="prevSlide inactiveButton"></div>88 <div class="nextSlide inactiveButton"></div>89 </div>90 <div class="clear"></div>91 </div>92 124 </div> 93 <div class="footer">94 <input type="hidden" value="<?php echo get_option('expresscurate_curated_text', 'Curated from'); ?>" id="expresscurate_from" name="expresscurate_from"/>95 <input type="hidden" value="<?php echo get_option('expresscurate_autosummary', 5); ?>" id="expresscurate_autosummary" name="expresscurate_autosummary"/>96 <ul class="labels" id="curated_tags">97 <li class="markButton expresscurate_displayNone expresscurate_preventTextSelection"><span>mark keywords</span></li>98 </ul>99 <div class="clear"></div>100 <button class="curate right" id="expresscurate_insert" onclick="return false;"><?php echo __('Curate into post', ExpressCurate_Actions::PLUGIN_FOLDER) ?></button>101 <div class="clear"></div>102 </div>103 </div>104 125 </div> 105 126 <div id="expresscurate_loading"> 106 <img src="<?php echo plugin_dir_url(__FILE__); ?>../images/loading.gif" id="img-load"/>127 <img src="<?php echo plugin_dir_url(__FILE__); ?>../images/loading.gif" id="img-load"/> 107 128 </div> 108 129 109 130 <script type="text/html" id="tmpl-dialogCuratedImage"> 110 <li id="tcurated_image_{{data.index}}" class="tcurated_image" data-id="{{data.index}}" style="background-image: url({{data.url}})"></li> 131 <li id="tcurated_image_{{data.index}}" class="tcurated_image" data-id="{{data.index}}" 132 style="background-image: url({{data.url}})"></li> 111 133 </script> 112 134 <script type="text/html" id="tmpl-dialogCuratedParagraphs"> 113 <li id="tcurated_text_{{data.index}}" title="{{data.title}}" class="tcurated_text expresscurate_tag_{{data.tag}}" data-id="{{data.index}}">{{data.title}}</li> 135 <li id="tcurated_text_{{data.index}}" title="{{data.title}}" class="tcurated_text expresscurate_tag_{{data.tag}}" 136 data-id="{{data.index}}">{{data.title}} 137 </li> 114 138 </script> 115 139 <script type="text/html" id="tmpl-dialogCuratedtags"> 116 <li class="curated_post_tag" id="curated_post_tag_{{data.index}}"><span class="tag">{{data.tag}}</span><a href="#" class="remove" data-id="{{data.index}}"></a></li> 140 <li class="curated_post_tag" id="curated_post_tag_{{data.index}}"><span class="tag">{{data.tag}}</span><a href="#" 141 class="remove" 142 data-id="{{data.index}}"></a> 143 </li> 117 144 </script> 118 145 <script type="text/html" id="tmpl-dialogMarkButton"> … … 120 147 </script> 121 148 <script type="text/html" id="tmpl-dialogInsertTags"> 122 <li class="curated_post_tag" id="curated_post_tag_{{data.index}}"><a href="#" data-id="{{data.index}}">X</a><span>{{data.tag}}</span></li> 149 <li class="curated_post_tag" id="curated_post_tag_{{data.index}}"><a href="#" data-id="{{data.index}}">X</a><span>{{data.tag}}</span> 150 </li> 123 151 </script> 124 152 <script type="text/html" id="tmpl-dialogSearchParagraphs"> … … 134 162 </script> 135 163 <script type="text/html" id="tmpl-dialogCuratedHeadings"> 136 <li class="curated_heading" id="curated_heading_{{data.index}}" data-tag="{{data.index}}" title="{{data.content}}">{{data.index}}</li> 164 <li class="curated_heading" id="curated_heading_{{data.index}}" data-tag="{{data.index}}" title="{{data.content}}"> 165 {{data.index}} 166 </li> 137 167 </script> 138 168 <script type="text/html" id="tmpl-dialogCuratedDescription"> … … 148 178 </ul> 149 179 <div id="" class="tab-content"> 150 <textarea id="expresscurate_socialEmbed" placeholder="Embed code" class="expresscurate_disableInputStyle"></textarea> 180 <textarea id="expresscurate_socialEmbed" placeholder="Embed code" 181 class="expresscurate_disableInputStyle"></textarea> 151 182 <span class="expresscurate_errorMessage"></span> 152 183 </div> -
expresscurate/trunk/templates/feed_dashboard.php
r1129694 r1137344 6 6 <div class="expresscurate_feed_dashboard expresscurate_Styles wrap"> 7 7 <div class="expresscurate_headBorderBottom expresscurate_headerPart expresscurate_OpenSansRegular"> 8 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>8 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 9 9 10 10 <h2>RSS Feeds</h2> … … 26 26 <li> 27 27 <a href="<?php echo $feed_url['feed_url'] ?>" 28 target="_newtab"><?php echo $feed_url['feed_ url']; ?></a>28 target="_newtab"><?php echo $feed_url['feed_title']; ?><br /><small><?php echo $url; ?></small></a> 29 29 <span class="postsCount expresscurate_floatRight"> 30 30 <?php echo $feed_url['post_count']; ?> … … 50 50 <script type="text/html" id="tmpl-rssfeedItem"> 51 51 <li> 52 <a target="_newtab" href="{{data.feed_url}}">{{data.feed_ url}}</a>52 <a target="_newtab" href="{{data.feed_url}}">{{data.feed_title}}<br/><small>{{data.link}}</small></a> 53 53 <span class="postsCount expresscurate_floatRight">{{data.post_count}} 54 54 <input type="hidden" name="expresscurate_feed_url" value="{{data.feed_url}}"/> -
expresscurate/trunk/templates/feed_list.php
r1129694 r1137344 14 14 15 15 if (!empty($contentList)) { 16 foreach ($contentList as $key => $row) { 17 if (is_array($row) && count($row) > 0) { 18 foreach ($row as $content) { 19 $content['fullLink'] = $content['link']; 20 $extracted_url = extract_google_feed_url($content['link'], $row); 21 if ($extracted_url) { 22 $url = $extracted_url; 23 } else { 24 $url = $content['link']; 25 } 26 $content['link'] = $url; 27 $content['domain'] = parse_url($url, PHP_URL_SCHEME) . "://" . parse_url($url, PHP_URL_HOST); 28 array_push($sorted_feeds, $content); 16 $feed_content = $contentList['content']; 17 if (is_array($feed_content) && count($feed_content) > 0) { 18 foreach ($feed_content as $content) { 19 $content['fullLink'] = $content['link']; 20 $extracted_url = extract_google_feed_url($content['link'], $feed_content); 21 if ($extracted_url) { 22 $url = $extracted_url; 23 } else { 24 $url = $content['link']; 29 25 } 26 $content['link'] = $url; 27 $content['domain'] = parse_url($url, PHP_URL_SCHEME) . "://" . parse_url($url, PHP_URL_HOST); 28 array_push($sorted_feeds, $content); 30 29 } 31 30 } … … 33 32 } 34 33 35 wp_clear_scheduled_hook('expresscurate_pull_feeds');36 $pull_feed_interval = (get_option('expresscurate_pull_hours_interval')) ? get_option('expresscurate_pull_hours_interval') : 1;37 wp_schedule_event(strtotime("+" . $pull_feed_interval . " hour"), 'hourly', 'expresscurate_pull_feeds');38 34 $nextPullTime = human_time_diff(wp_next_scheduled('expresscurate_pull_feeds'), time()); 39 40 35 ?> 41 36 <input id="adminUrl" type="hidden" value="<?php echo get_admin_url(); ?>"/> … … 45 40 } ?>"> 46 41 <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular"> 47 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>42 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 48 43 49 44 <h2>Content Feed</h2> … … 56 51 </div> 57 52 <div class="controlsWrap"> 58 <ul class="feedListControls expresscurate_preventTextSelection expresscurate_controls expresscurate_displayNone">53 <ul class="feedListControls expresscurate_preventTextSelection expresscurate_controls "> 59 54 <li class="check"> 60 55 <span class="tooltip">select / deselect</span> … … 69 64 <span class="tooltip">curate</span> 70 65 </li> 71 <!--<li class="pull active expresscurate_floatRight"> 72 <span class="tooltip">pull</span> 73 </li> 74 <li class="pullTime active expresscurate_floatRight"> 75 next update: 76 <p>in <?php /*echo $nextPullTime; */?></p> 77 </li>--> 66 <?php if (strlen(get_option('expresscurate_links_rss', '')) > 2) { ?> 67 <li class="pull active expresscurate_floatRight"> 68 <span class="tooltip">pull</span> 69 <span class="loading"></span> 70 </li> 71 <li class="pullTime active expresscurate_floatRight"> 72 next update: 73 <p>in <?php echo $nextPullTime; ?></p> 74 </li> 75 <?php } ?> 78 76 <li class="layout expresscurate_floatRight"> 79 77 <span class="tooltip"><?php if (get_option('expresscurate_bookmark_layout', '') == 'single') { … … 93 91 $i = 0; 94 92 ?> 95 <ul class="expresscurate_feedBoxes expresscurate_masonryWrap"><?php93 <ul id="expresscurate_feedBoxes" class="expresscurate_feedBoxes expresscurate_masonryWrap"><?php 96 94 foreach ($sorted_feeds as $key => $item) { 97 95 ?> … … 157 155 ?></ul><?php 158 156 } ?> 159 <label class="expresscurate_notDefined expresscurate_displayNone">Your content feed is empty. Configure <a 157 <label class="expresscurate_notDefined expresscurate_displayNone">Your content feed is 158 empty. <?php echo (strlen(get_option('expresscurate_links_rss', '')) > 2) ? '' : 'Configure <a 160 159 href="admin.php?page=expresscurate_feeds">RSS feeds</a> to 161 start. </label>160 start.'; ?></label> 162 161 163 162 <form method="POST" action="<?php echo get_admin_url() ?>post-new.php#expresscurate_sources_collection" -
expresscurate/trunk/templates/keywords.php
r1129694 r1137344 8 8 <input type="hidden" id="expresscurate_plugin_dir" value="<?php echo plugin_dir_url(__FILE__); ?>"/> 9 9 <label>Keywords Dashboard</label> 10 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions?10 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? 11 11 <span>Submit here!</span></a> 12 12 <br/> -
expresscurate/trunk/templates/news.php
r1075868 r1137344 1 1 <div class="expresscurate_Styles wrap "> 2 2 <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular"> 3 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>3 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 4 4 <h2>News</h2> 5 5 </div> -
expresscurate/trunk/templates/settings.php
r1129694 r1137344 1 1 <div class="expresscurate expresscurate_Styles expresscurate_settings wrap"> 2 2 <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular"> 3 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions?3 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? 4 4 <span>Submit here!</span></a> 5 5 … … 79 79 ?>" name="expresscurate_curated_text" size="50"/> 80 80 </li> 81 <li> 82 <p class="title">Open Original Article Link in a New Window/Tab<span scope="row" class="description "> 83 Select "Yes" if you want the original article link to be opened in a New Window/Tab. Select "No" if you want the link to be opened in the Same Window/Tab (default behavior). 84 </span></p> 85 86 <input class="expresscurate_displayNone" type="checkbox" id="expresscurate_curated_link_target" 87 name="expresscurate_curated_link_target" <?php 88 if (get_option('expresscurate_curated_link_target', 'on') == "on") { 89 echo 'checked'; 90 } 91 ?> /> 92 <label class="controls checkboxLabel" for="expresscurate_curated_link_target"></label> 93 94 </li> 81 95 <li> 82 96 <label for="expresscurate_max_tags" class="title">Max Number of Auto-suggested Tags<span … … 414 428 <li> 415 429 <div class="title"> 430 Content Pull Frequency 431 <div class="description"> 432 How frequently should ExpressCurate pull content (from RSS feeds, Alerts, etc) into your 433 <a href="#">Content Feed</a>? 434 </div> 435 </div> 436 <select class="controls" id="expresscurate_pull_hours_interval" 437 name="expresscurate_pull_hours_interval"> 438 <?php 439 for ($i = 1; $i < 14; $i++) { 440 ?> 441 <?php if ($i == 1) { ?> 442 <option value="<?php echo $i; ?>" <?php 443 if (get_option('expresscurate_pull_hours_interval') == $i) { 444 echo 'selected="selected"'; 445 } 446 ?>>Every hour 447 </option> 448 449 <?php } elseif ($i == 13) { ?> 450 <option value="<?php echo $i; ?>" <?php 451 if (get_option('expresscurate_pull_hours_interval') == $i) { 452 echo 'selected="selected"'; 453 } 454 ?>>Once a day 455 </option> 456 457 <?php } else { ?> 458 <option value="<?php echo $i; ?>" <?php 459 if (get_option('expresscurate_pull_hours_interval') == $i) { 460 echo 'selected="selected"'; 461 } 462 ?>>Every <?php echo $i; ?> hours 463 </option> 464 465 <?php 466 } 467 } 468 ?> 469 </select> 470 </li> 471 <li> 472 <div class="title"> 416 473 Keyword Match Email Alerts 417 474 <div class="description"> … … 467 524 </select> 468 525 </li> 469 <li>470 <div class="title">471 Content Pull Frequency472 <div class="description">473 How frequently should ExpressCurate pull content (from RSS feeds, Alerts, etc) into your474 <a href="#">Content Feed</a>?475 </div>476 </div>477 <select class="controls" id="expresscurate_pull_hours_interval"478 name="expresscurate_pull_hours_interval">479 <?php480 for ($i = 1; $i < 14; $i++) {481 ?>482 <?php if ($i == 1) { ?>483 <option value="<?php echo $i; ?>" <?php484 if (get_option('expresscurate_pull_hours_interval') == $i) {485 echo 'selected="selected"';486 }487 ?>>Every hour488 </option>489 490 <?php } elseif ($i == 13) { ?>491 <option value="<?php echo $i; ?>" <?php492 if (get_option('expresscurate_pull_hours_interval') == $i) {493 echo 'selected="selected"';494 }495 ?>>Once a day496 </option>497 498 <?php } else { ?>499 <option value="<?php echo $i; ?>" <?php500 if (get_option('expresscurate_pull_hours_interval') == $i) {501 echo 'selected="selected"';502 }503 ?>>Every <?php echo $i; ?> hours504 </option>505 506 <?php507 }508 }509 ?>510 </select>511 </li>512 526 </ul> 513 527 <div class="centerSave"> -
expresscurate/trunk/templates/websites.php
r1066998 r1137344 5 5 <div class="expresscurate_topSources expresscurate_Styles wrap"> 6 6 <div class="expresscurate_headBorderBottom expresscurate_headerPart expresscurate_OpenSansRegular"> 7 <a href="admin.php?page=expresscurate &type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>7 <a href="admin.php?page=expresscurate_support" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a> 8 8 <h2>Top Sources</h2> 9 9 <label class="pageDesc">Top sources where you have curated from.</label>
Note: See TracChangeset
for help on using the changeset viewer.