Plugin Directory

Changeset 1129694


Ignore:
Timestamp:
04/07/2015 03:53:49 PM (11 years ago)
Author:
expresscurate
Message:

new version v2.0.10 with changes:

  • 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.
  • Content Feed performance improvements.
  • Bug fixation for SEO meta robots=follow-nofollow, index-noidex
  • Other miscellaneous bug fixes and improvements.
Location:
expresscurate/trunk
Files:
1 added
32 edited

Legend:

Unmodified
Added
Removed
  • expresscurate/trunk/ExpressCurate.php

    r1115352 r1129694  
    55  Plugin URI: http://www.expresscurate.com/products
    66  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.9
     7  Version: 2.0.10
    88  Author: ExpressCurate
    99  Author URI: http://www.expresscurate.com
     
    119119
    120120
     121  function extract_google_feed_url($url,$row=null){
     122      if(strpos(parse_url($url,PHP_URL_SCHEME)."://www.google.com/url",$url)==0 && !empty($row)) {
     123          $url_query = explode("&",parse_url($url,PHP_URL_QUERY));
     124          foreach($url_query as $param) {
     125              if(strpos($param, 'url=') === 0) {
     126                  if (!array_key_exists(str_replace("url=", "", $param), $row)){
     127                      $output_url = str_replace("url=", "", $param);
     128                  }
     129                  else{
     130                      unset($row[$url]);
     131                  }
     132                  break;
     133              }
     134          }
     135      }
     136      return $output_url;
     137  }
     138
    121139  function cron_add_5min($schedules) {
    122140    $schedules['5min'] = array(
  • expresscurate/trunk/ExpressCurate_Actions.php

    r1115335 r1129694  
    3232    const MBSTRING = 'mbstring';
    3333
     34    const ALLOW_URL_OPEN = "allow_url_fopen";
    3435    //functions
    3536    const EXEC = 'exec';
     
    5556        $this->feedManager = new ExpressCurate_FeedManager();
    5657
    57         //add_shortcode('facebook', array(&$this, 'facebook_post'));
    5858        // register actions
    5959
     
    7070        add_action('init', array(&$this, 'buttons')); //'wpc_buttons'
    7171        add_action('init', array(&$this, 'include_api'));
     72        add_action('init',array(&$this,'add_oembed_facebook'));
    7273
    7374        add_filter('manage_edit-post_columns', array(&$this, 'curated_column_register'));
     
    8283        add_action('wp_head', array(&$this, 'advanced_seo_update_canonical_url'));
    8384        add_filter('wp_title', array(&$this, 'advanced_seo_update_title'));
    84         add_filter('tiny_mce_before_init', array(&$this, 'override_mce_options'));
    85 
    86     }
    87 
    88     public function override_mce_options($init)
    89     {
    90         $ext = 'script[charset|async|defer|language|src|type]';
    91 
    92         //if extended_valid_elements alreay exists, add to it
    93         //otherwise, set the extended_valid_elements to $ext
    94         if (isset($init['extended_valid_elements'])) {
    95             $init['extended_valid_elements'] .= ',' . $ext;
    96         } else {
    97             $init['extended_valid_elements'] = $ext;
    98         }
    99 
    100         return $init;
    101     }
     85
     86    }
     87
    10288
    10389    /**
     
    144130        add_action('wp_ajax_expresscurate_keywords_add_keyword', array($this->keywords, 'add_keyword'));
    145131        add_action('wp_ajax_expresscurate_keywords_get_stats', array($this->keywords, 'get_stats'));
     132        add_action('wp_ajax_expresscurate_get_post_analytics_stats', array($this->keywords, 'get_post_analytics_stats'));
    146133        add_action('wp_ajax_expresscurate_keywords_get_suggestions', array($this->keywords, 'suggestKeywordsFromGoogle'));
    147134        add_action('wp_ajax_expresscurate_keywords_delete_keyword', array($this->keywords, 'delete_keyword'));
     
    179166        add_action('wp_ajax_dashboard_items_order', array(&$this, 'dashboard_items_order'));
    180167
     168        add_action('wp_ajax_expresscurate_manual_pull_feed', array($this->feedManager, 'manual_pull_feed'));
    181169
    182170        add_action('wp_dashboard_setup', array(&$this, 'add_dashboard_widgets'));
     
    236224        register_setting('expresscurate-sitemap-group', 'expresscurate_sitemap_priority_manual_value');
    237225        register_setting('expresscurate-sitemap-group', 'expresscurate_sitemap_archiving');
    238         //register_setting('expresscurate-sitemap-group', 'expresscurate_sitemap_token');
     226        register_setting('expresscurate-changed-post-status', 'expresscurate_changed_post_status');
    239227        register_setting('expresscurate-sitemap-generation-group', 'expresscurate_sitemap_generation_last_date');
    240228    }
     
    247235    }
    248236
    249     /*
    250     public function facebook_post($atts)
    251     {
    252         $atts = shortcode_atts(array(
    253             'src' => ' '
    254         ), $atts, 'facebook');
    255         $href="{$atts['src']}";
    256         $iframe='<div id="fb-root"></div>
    257             <script>(function(d, s, id) {
    258               var js, fjs = d.getElementsByTagName(s)[0];
    259               if (d.getElementById(id)) return;
    260               js = d.createElement(s); js.id = id;
    261               js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=1015040711858893&version=v2.0";
    262               fjs.parentNode.insertBefore(js, fjs);
    263             }(document, "script", "facebook-jssdk"));</script>
    264             <div class="fb-post" data-href="'.$href.'" data-width="100%"></div>';
    265 
    266          return $iframe;
    267     }
    268 */
     237    function add_oembed_facebook(){
     238        wp_oembed_add_provider( 'http://www.facebook.com/*', 'http://api.embed.ly/v1/api/oembed');
     239    }
     240
    269241    public function load_source()
    270242    {
     
    320292        array_push($buttons, 'righttextbox');
    321293        array_push($buttons, 'noFollow');
    322         array_push($buttons, 'wordCount');
     294        if(get_option('expresscurate_seo', '') == "on"){
     295            array_push($buttons, 'wordCount');
     296        }
    323297        array_push($buttons, 'addKeyword');
    324298        return $buttons;
     
    349323        $context .= "<a class='button expresscurate' title='{$title}'
    350324    href='#' id='expresscurate_open-modal'>
    351     <span class='expresscurate_button_icon' /></span> Curate Content</a>";
     325    <span class='expresscurate_button_icon' /></span> Curate Content</a>
     326    <a class='button expresscurateSocial' title='{$title}'
     327    href='#' id='expresscurate_socialModal'>
     328    <span class='expresscurate_socialModal' /></span> Embed</a>";
    352329
    353330        return $context;
     
    636613            $this->generate_sitemap();
    637614        }
    638         if ("publish" == $new_status && "publish" != $old_status) {
    639             update_option('expresscurate_post_status', 'publish');
     615        if ("publish" == $new_status && "publish" != $old_status && (!empty($_POST['expresscurate_sources']) || get_post_meta($post->ID, '_is_expresscurate', true)==1)) {
     616            update_option('expresscurate_changed_post_status', 'publish');
    640617        }
    641618    }
     
    673650    public function save_post($post_id)
    674651    {
    675 
    676652        $post_type = get_post_type($post_id);
    677653
     
    735711            update_post_meta($post_id, '_expresscurate_advanced_seo_social_shortdesc', esc_attr($expresscurate_advanced_seo_social_shortdesc));
    736712            update_post_meta($post_id, '_expresscurate_advanced_seo_social_desc', esc_attr($expresscurate_advanced_seo_social_desc));
     713
     714            //post analysis notification
     715            $expresscurate_post_analysis_notification = isset($_POST['expresscurate_post_analysis_notification']) ? $_POST['expresscurate_post_analysis_notification'] : '';
     716
     717            update_post_meta($post_id, '_expresscurate_post_analysis_notification', esc_attr($expresscurate_post_analysis_notification));
    737718        }
    738719
     
    831812                            // all set, try to download it
    832813                            require_once(ABSPATH . 'wp-admin/includes/image.php');
    833                             $content_manager = new ExpressCurate_HtmlParser($image_from);
     814                            $content_manager = new ExpressCurate_HtmlParser($image, true, $image_from);
    834815                            // download
    835                             $image_data = $content_manager->file_get_contents_utf8($image, false, false);
     816                            $image_data = $content_manager->download();
    836817                            if (false === $image_data) {
    837818                                $warning[$post_id]['download_failure'] = "Unable download cover image";
     
    883864                            $image_path = parse_url($image);
    884865                            $file = $image_path['path'];
    885 //                            if (wp_mkdir_p($upload_dir['path'])) {
    886 //                                $file = $upload_dir['path'] . '/' . $image_filename;
    887 //                            } else {
    888 //                                $file = $upload_dir['basedir'] . '/' . $image_filename;
    889 //                            }
    890866                            $file = strtok($file, '?');
    891867
     
    961937        }
    962938
    963         $post_issues = $this->post_analysis($post_content, has_post_thumbnail($post_id));
     939        $post_issues = get_post_meta($post_id, '_expresscurate_post_analysis_notification', true);
    964940        if ($post_issues > 0) {
    965941            $warning = get_option('expresscurate_not_writable_warning');
     
    970946            update_option('expresscurate_not_writable_warning', $warning);
    971947        }
    972 
    973     }
    974 
    975 
    976     public function post_analysis($post_content, $has_featured)
    977     {
    978         $issues = 0;
    979         if (strlen($post_content) > 1) {
    980             // Check words count
    981             preg_match_all('/[\pL\pN\pPd]+/u', strip_tags($post_content), $matches);
    982             $words_count = count($matches[0]);
    983             if ($words_count < 700 || $words_count > 1600) {
    984                 $issues++;
    985             }
    986 
    987             // Get blockquote
    988             $htmlParser = new ExpressCurate_HtmlParser();
    989 
    990             $text_inside_blockquote = $htmlParser->getTextBetweenTags('blockquote', $post_content);
    991 
    992 
    993             if (count($text_inside_blockquote) > 0) {
    994                 $words_count_of_blockquote = 0;
    995                 foreach ($text_inside_blockquote as $content) {
    996                     preg_match_all('/[\pL\pN\pPd]+/u', strip_tags($content), $matches);
    997                     $words_count_of_blockquote += count($matches[0]);
    998                 }
    999                 if (round(($words_count_of_blockquote / $words_count) * 100) > 20) {
    1000                     $issues++;
    1001                 }
    1002             }
    1003 
    1004             $img_in_post = $htmlParser->getTextBetweenTags('img', $post_content);
    1005             if (count($img_in_post) < 1) {
    1006                 $issues++;
    1007             }
    1008         } else {
    1009             $issues++;
    1010         }
    1011 
    1012         if (!$has_featured) {
    1013             $issues++;
    1014         }
    1015         return $issues;
    1016948
    1017949    }
     
    12111143    private function add_advanced_seo_metas($post_id, &$meta_string)
    12121144    {
    1213         $nofollow = get_post_meta($post_id, '_expresscurate_advanced_seo_nofollow', true) == 'on' ? 'NOFOLLOW' : '';
    1214         $noindex = get_post_meta($post_id, '_expresscurate_advanced_seo_noindex', true) == 'on' ? 'NOINDEX' : '';
     1145        $nofollow = get_post_meta($post_id, '_expresscurate_advanced_seo_nofollow', true) == 'off' ? 'NOFOLLOW' : '';
     1146        $noindex = get_post_meta($post_id, '_expresscurate_advanced_seo_noindex', true) == 'off' ? 'NOINDEX' : '';
    12151147        if (!empty($nofollow) || !empty($noindex)) {
    12161148            $meta_string .= sprintf("<meta name=\"ROBOTS\" content=\"%s\" />\n", implode(', ', array_filter(array($nofollow, $noindex))));
     
    16471579        }
    16481580
    1649         if (!extension_loaded(self::CURL)) {
    1650             $extWarnings[] = self::CURL;
    1651         }
    16521581
    16531582        if (!extension_loaded(self::MBSTRING)) {
    16541583            $extWarnings[] = self::MBSTRING;
     1584        }
     1585
     1586        if (!ExpressCurate_HtmlParser::supportsDownload()) {
     1587            echo '<div class="update-nag">You should activate either curl extension or allow_url_fopen setting.</div>';
    16551588        }
    16561589
  • expresscurate/trunk/ExpressCurate_AjaxExportAPI.php

    r1115335 r1129694  
    3535        $data["keywords"] = array();
    3636        $data["featured_image"] = 0;
     37        $data["smart_publishing"] = get_option('expresscurate_publish', '') == 'on' ? get_option('expresscurate_manually_approve_smart', 'off') : 'off';
     38        $data["curated_from_prefix"] = get_option("expresscurate_curated_text", 'See full story on');
    3739        if (current_user_can('edit_posts')) {
    3840            $categories = get_categories(array("hide_empty" => 0));
     
    7678    {
    7779        $data = $_REQUEST;
    78         //$options = array('http' => array('user_agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36'));
    79         $options = array('http' => array('user_agent' => USER_AGENT,' follow_location'=>1,'max_redirects'=>5,'request_fulluri '=>TRUE));
    80         if(preg_match("/(^https:\/\/)/i", $url)!=false){
    81             $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false);
    82         }
    83         $context = stream_context_create($options);
    8480        if (!$data['img_url'] && !$data['img_url2']) {
    8581            $data_check = array('status' => "error", 'msg' => "Data is empty!");
    8682        } else {
    87             $content_manager = new ExpressCurate_HtmlParser($data['img_url']);
    88             $img = $content_manager->file_get_contents_utf8($data['img_url'], true);  //@file_get_contents($data['img_url'], false, $context);
    89             $http_response_header = $img['http_status'];
    90             $img = $img['content'];
    91             if (!$img) {
    92                 //$img = @file_get_contents($data['img_url2'], false, $context);
    93                 $img = $content_manager->file_get_contents_utf8($data['img_url2'], true);
    94                 $http_response_header = $img['http_status'];
    95                 $img = $img['content'];
    96             }
    97             if ($img) {
    98                 if ((is_array($http_response_header) && ($http_response_header[0] == "HTTP/1.1 200 OK" || strpos($http_response_header[0], '200'))) || $http_response_header == "HTTP/1.1 200 OK" || $http_response_header == 200 || $http_response_header == 'HTTP\/1.1 200 OK') {
    99                     $data_check = array('status' => 'success', 'statusCode' => 200);
    100                 } else if ($http_response_header == "HTTP/1.1 403 Forbidden" || $http_response_header == 403) {
    101                     $data_check = array('status' => 'fail', 'statusCode' => 403);
    102                 } else {
    103                     $data_check = array('status' => 'fail', 'statusCode' => $http_response_header[0]);
    104                 }
    105             } else {
     83            $content_manager = new ExpressCurate_HtmlParser($data['img_url'], true);
     84            $img = $content_manager->download();
     85            if ($content_manager->isHTTPStatusOK() === false) {
     86                $content_manager = new ExpressCurate_HtmlParser($data['img_url2'], true);
     87                $img = $content_manager->download();
     88            }
     89           
     90            if ($content_manager->isHTTPStatusOK() === false) {
    10691                $data_check = array('status' => "error", 'msg' => "Images not found!");
     92            } else {
     93                $statusCode = $content_manager->getHTTPStatusCode();
     94               
     95                $data_check = array('status' => $statusCode == 200 ? 'success' : 'fail', 'statusCode' => $statusCode);
    10796            }
    10897        }
     
    131120                mkdir($upload_dir['basedir'] . '/expresscurate_tmp/' . $post_id, 0777);
    132121            }
    133             $options = array('http' => array('user_agent' => USER_AGENT,' follow_location'=>1,'max_redirects'=>5,'request_fulluri '=>TRUE));
    134             if(preg_match("/(^https:\/\/)/i", $url)!=false){
    135                 $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false);
    136             }
    137             $context = stream_context_create($options);
     122
    138123            if (count($images) > 0 && is_writable($upload_dir['path'])) {
    139                 $content_manager = new ExpressCurate_HtmlParser($images[0]);
    140                 for ($i = 0; $i < count($images); $i++) {
     124                for ($i = 0, $len = count($images); $i < $len; $i++) {
    141125                    $image = strtok($images[$i], '?');
    142                     $image_data = $content_manager->file_get_contents_utf8($images[$i]);
     126                   
     127                    // TODO create new parser
     128                    // TODO get some referer
     129                    $content_manager = new ExpressCurate_HtmlParser($images[$i], true, $images[0]);
     130                    $image_data = $content_manager->download();
    143131                    $filename[$i] = basename($image);
    144132                    if (wp_mkdir_p($upload_dir['path'])) {
     
    187175        $result = false;
    188176        $data = $_REQUEST;
     177       
    189178        if (isset($data['force_draft']) && $data['force_draft'] === 1) {
    190179            $post_status = 'draft';
     180        } else if(isset($data['publishing']) && (($publishingType = $data['publishing']) == 'date' || $publishingType == 'hour')) {
     181            $post_status = 'future';
    191182        } else {
    192183            $post_status = get_option('expresscurate_post_status', '') ? get_option('expresscurate_post_status', '') : 'draft';
     
    216207            $result = json_encode(array('status' => "error", 'msg' => "Data is empty!"));
    217208        }
    218 
    219         //Smart publishing
    220         if (get_option('expresscurate_publish', '') == 'on') {
    221             $smartPublish = 1;
    222 
    223             if (get_option('expresscurate_manually_approve_smart') == 'on') {
    224                 $smartPublish = 0;
    225             }
    226             update_post_meta($post_id, '_expresscurate_smart_publish', $smartPublish);
    227         }
     209       
    228210        echo $result;
    229211        die;
     
    292274            $post_cats = $data['terms'];
    293275        }
     276       
     277        $post_date = time();
     278        $publishingOptions = $data['publishing'];
     279        $publishingType = $publishingOptions['type'];
     280        $publishingValue = $publishingOptions['value'];
     281       
     282        if($publishingType == 'date') {
     283            $post_date = strtotime($publishingValue);
     284        } else if($publishingType == 'hour') {
     285            $post_date = strtotime('+' . $publishingValue . ' hours');
     286        }
     287       
    294288        $details = array(
    295             'post_content' => str_replace("&nbsp;", " ", $data['content']),
    296             'post_author' => get_current_user_id(),
    297             'post_title' => $data['title'],
    298             'post_status' => $post_status,
     289            'post_content'  => str_replace("&nbsp;", " ", $data['content']),
     290            'post_author'   => get_current_user_id(),
     291            'post_title'    => $data['title'],
     292            'post_status'   => $post_status,
    299293            'post_category' => $post_cats,
    300             'post_type' => get_option('expresscurate_def_post_type', 'post')
     294            'post_type'     => get_option('expresscurate_def_post_type', 'post'),
     295            'post_date_gmt' => gmdate('Y-m-d H:i:s', $post_date)
    301296        );
    302297
     
    317312        }
    318313        if ($post_status == 'draft' && get_option('expresscurate_publish', '') == 'on') {
    319             update_post_meta($post_id, '_expresscurate_smart_publish', 1);
     314            $smartPublish = 1;
     315
     316            if(get_option('expresscurate_manually_approve_smart') == 'on') {
     317                $smartPublishForced = ($publishingType == 'smartpublish') && ($publishingValue == 'true');
     318                $smartPublish = $smartPublishForced ? 1 : 0;
     319            }
     320           
     321            update_post_meta($post_id, '_expresscurate_smart_publish', $smartPublish);
     322        }
     323       
     324        // add source
     325        if(isset($data['source'])) {
     326           
     327            $expresscurate_sources_meta_value = array();
     328            $expresscurate_sources_meta_value[0]['title'] = $source['original_title'];
     329            $expresscurate_sources_meta_value[0]['link'] = $source['url'];
     330            $expresscurate_sources_meta_value[0]['domain'] = $source['domain'];
     331           
     332            update_post_meta($post_id, '_expresscurate_curated_data', wp_slash($expresscurate_sources_meta_value));
    320333        }
    321334
     
    387400        die;
    388401    }
    389 
    390 
    391402}
    392403
  • expresscurate/trunk/ExpressCurate_ContentManager.php

    r1106118 r1129694  
    3535
    3636      public function get_article($url = false, $echo = true) {
    37         if (!$url) {
    38           $url = $this->_post('expresscurate_source', '');
    39         }
    40         $url = preg_replace( '/\s+/', '', $url );
    41         if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
    42           $url = 'http://' . $url;
    43         }
    44         if (strlen($url) < 1) {
    45           $data = array('status' => 'error', 'error' => 'Please enter the URL');
    46           if ($echo) {
    47             echo json_encode($data);
    48             die();
     37        if(!ExpressCurate_HtmlParser::supportsDownload()){
     38          echo json_encode(array('status' => 'error', 'error' => 'You should activate either curl extension or allow_url_fopen setting.'));
     39          die;
     40        }else{
     41          if (!$url) {
     42            $url = $this->_post('expresscurate_source', '');
     43          }
     44          $url = preg_replace( '/\s+/', '', $url );
     45          if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
     46            $url = 'http://' . $url;
     47          }
     48          if (strlen($url) < 1) {
     49            $data = array('status' => 'error', 'error' => 'Please enter the URL');
     50            if ($echo) {
     51              echo json_encode($data);
     52              die();
     53            } else {
     54              return $data;
     55            }
     56          }
     57          if (filter_var($url, FILTER_VALIDATE_URL) === FALSE || !preg_match('#(http|https)\:\/\/[aA-zZ0-9\.]+\.[aA-zZ\.]+#',$url)) {
     58            $data = array('status' => 'error', 'error' => 'Please enter a valid URL');
     59            if ($echo) {
     60              echo json_encode($data);
     61              die();
     62            } else {
     63              return $data;
     64            }
     65          }
     66          if ($this->_get('check', '') == 1) {
     67            $data_check = array();
     68            $curated_urls = $this->get_meta_values('_expresscurate_link_', $url);
     69            if (isset($curated_urls[0]) && isset($curated_urls[0]['meta_value'])) {
     70              $data_check["status"] = "notification";
     71              $data_check["msg"] = "Warning! This page has been curated before";
     72            }
     73            if ($echo) {
     74              echo json_encode($data_check);
     75              die();
     76            } else {
     77              return $data_check;
     78            }
    4979          } else {
    50             return $data;
    51           }
    52         }
    53         if (filter_var($url, FILTER_VALIDATE_URL) === FALSE || !preg_match('#(http|https)\:\/\/[aA-zZ0-9\.]+\.[aA-zZ\.]+#',$url)) {
    54           $data = array('status' => 'error', 'error' => 'Please enter a valid URL');
    55           if ($echo) {
    56             echo json_encode($data);
    57             die();
    58           } else {
    59             return $data;
    60           }
    61         }
    62         if ($this->_get('check', '') == 1) {
    63           $data_check = array();
    64           $curated_urls = $this->get_meta_values('_expresscurate_link_', $url);
    65           if (isset($curated_urls[0]) && isset($curated_urls[0]['meta_value'])) {
    66             $data_check["status"] = "notification";
    67             $data_check["msg"] = "Warning! This page has been curated before";
    68           }
    69           if ($echo) {
    70             echo json_encode($data_check);
    71             die();
    72           } else {
    73             return $data_check;
    74           }
    75         } else {
    76           $tags = $this->_post('tags', '');
    77           $HtmlParser = new ExpressCurate_HtmlParser($url);
    78           $article = $HtmlParser->getHtml($tags);
    79           if ($echo == true) {
    80             echo json_encode($article);
    81             die;
    82           } else {
    83             return $article;
     80            $HtmlParser = new ExpressCurate_HtmlParser($url);
     81            $article = $HtmlParser->getContents();
     82            if ($echo == true) {
     83              echo json_encode($article);
     84              die;
     85            } else {
     86              return $article;
     87            }
    8488          }
    8589        }
     
    101105      }
    102106
    103       public function _post($data, $default) {
     107      private function _post($data, $default) {
    104108        return isset($_POST[$data]) ? $_POST[$data] : $default;
    105109      }
    106110
    107       public function _get($data, $default) {
     111      private function _get($data, $default) {
    108112        return isset($_GET[$data]) ? $_GET[$data] : $default;
    109113      }
    110 
    111114}
  • expresscurate/trunk/ExpressCurate_FeedManager.php

    r1115335 r1129694  
    3232    {
    3333        global $wpdb;
    34         $url = isset($url) ? $url : $_REQUEST['url'];
    35         $url = trim($url);
    36 
    37         if (isset($url)) {
    38             $result = array();
    39             $curated_links_rss = get_option('expresscurate_links_rss', '');
    40             if ($curated_links_rss) {
    41                 $curated_links_rss = json_decode($curated_links_rss, true);
    42             } else {
    43                 $curated_links_rss = array();
    44             }
    45 
    46             //$url = expresscurate_normalise_url($url, true);
    47             $rssUrl = isset($rssUrl) ? $rssUrl : $this->getRssUrl($url);
    48 
    49             if (!isset($curated_links_rss[$rssUrl])) {
    50                 if (filter_var($rssUrl, FILTER_VALIDATE_URL)) {
    51                     $result['status'] = 'success';
    52                     $metas = $wpdb->get_results(
    53                         "SELECT post_id
     34        if(!ExpressCurate_HtmlParser::supportsDownload()){
     35            $result = array("status"=>"You should activate either curl extension or allow_url_fopen setting.");
     36        }else{
     37            $url = isset($url) ? $url : $_REQUEST['url'];
     38            $url = trim($url);
     39
     40            if (isset($url)) {
     41                $result = array();
     42                $curated_links_rss = get_option('expresscurate_links_rss', '');
     43                if ($curated_links_rss) {
     44                    $curated_links_rss = json_decode($curated_links_rss, true);
     45                } else {
     46                    $curated_links_rss = array();
     47                }
     48
     49                //$url = expresscurate_normalise_url($url, true);
     50                $rssUrl = isset($rssUrl) ? $rssUrl : $this->getRssUrl($url);
     51
     52                if (!isset($curated_links_rss[$rssUrl])) {
     53                    if (filter_var($rssUrl, FILTER_VALIDATE_URL)) {
     54                        $result['status'] = 'success';
     55                        $metas = $wpdb->get_results(
     56                            "SELECT post_id
    5457                   FROM $wpdb->postmeta
    5558                   WHERE meta_key LIKE  '%_expresscurate_link_%' AND meta_value LIKE '%" . $url . "%' GROUP BY post_id");
    5659
    5760
    58                     $curated_links_rss[$rssUrl]['feed_url'] = $result['feed_url'] = $rssUrl;
    59                     $curated_links_rss[$rssUrl]['post_count'] = $result['post_count'] = count($metas);
    60                     //  var_dump($curated_links_rss);die;
    61                     $curated_links_rss = json_encode($curated_links_rss);
    62                     update_option('expresscurate_links_rss', $curated_links_rss);
    63                 } elseif ($rssUrl === null) {
    64                     $result['status'] = 'No RSS feed found at this URL.';
     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.';
     68                    } else {
     69                        $result['status'] = 'Invalid RSS URL.';
     70                    }
    6571                } else {
    66                     $result['status'] = 'Invalid RSS URL.';
    67                 }
    68             } else {
    69                 $result['status'] = 'URL already exists.';
    70             }
    71         } else {
    72             $result['status'] = 'Something went wrong. Please check the URL. If the problem persists, please contact us.';
     72                    $result['status'] = 'URL already exists.';
     73                }
     74            } else {
     75                $result['status'] = 'Something went wrong. Please check the URL. If the problem persists, please contact us.';
     76            }
    7377        }
    7478        echo json_encode($result);
     79
    7580        die;
    7681    }
     
    114119        die;
    115120    }
    116 
    117121
    118122    public function get_curated_links()
     
    162166        }
    163167        wp_reset_postdata();
    164 
    165         foreach ($curated_links as $key => $top_link) {
    166             $websiteUrl = $top_link['link'];
    167             $rssUrl = $this->getRssUrl($websiteUrl);
    168             if ($rssUrl && isset($curated_links_rss[$rssUrl])) {
    169                 $feed_status = 'rssStatusYes';
    170             } else {
    171                 if ($rssUrl) {
    172                     $feed_status = 'rssStatusAdd';
     168        if(ExpressCurate_HtmlParser::supportsDownload()){
     169            foreach ($curated_links as $key => $top_link) {
     170                $websiteUrl = $top_link['link'];
     171                $rssUrl = $this->getRssUrl($websiteUrl);
     172                if ($rssUrl && isset($curated_links_rss[$rssUrl])) {
     173                    $feed_status = 'rssStatusYes';
    173174                } else {
    174                     $feed_status = 'rssStatusNo';
    175                 }
    176             }
    177             $top_sources_rss['links'][$websiteUrl] = array(
    178                 'post_ids' => array($top_link['post_id']),
    179                 'feed_options' => array(
    180                     'feed_url' => $rssUrl,
    181                     'feed_status' => $feed_status,
    182                     'type' => 'feed')
    183             );
    184             $top_sources_rss['links'][$websiteUrl]['post_ids'] = array_unique($top_sources_rss['links'][$websiteUrl]['post_ids']);
    185             $top_sources_rss['links'][$websiteUrl]['post_count'] = count($top_sources_rss['links'][$websiteUrl]['post_ids']);
    186         }
    187 
    188         @uasort($top_sources_rss['links'], array($this, "sort_by_count"));
    189         $top_sources_rss['date'] = date('Y-m-d H:i:s');
    190         $top_sources_rss_save = json_encode($top_sources_rss);
    191         update_option('expresscurate_top_sources_rss', $top_sources_rss_save);
     175                    if ($rssUrl) {
     176                        $feed_status = 'rssStatusAdd';
     177                    } else {
     178                        $feed_status = 'rssStatusNo';
     179                    }
     180                }
     181                $top_sources_rss['links'][$websiteUrl] = array(
     182                    'post_ids' => array($top_link['post_id']),
     183                    'feed_options' => array(
     184                        'feed_url' => $rssUrl,
     185                        'feed_status' => $feed_status,
     186                        'type' => 'feed')
     187                );
     188                $top_sources_rss['links'][$websiteUrl]['post_ids'] = array_unique($top_sources_rss['links'][$websiteUrl]['post_ids']);
     189                $top_sources_rss['links'][$websiteUrl]['post_count'] = count($top_sources_rss['links'][$websiteUrl]['post_ids']);
     190            }
     191
     192            @uasort($top_sources_rss['links'], array($this, "sort_by_count"));
     193            $top_sources_rss['date'] = date('Y-m-d H:i:s');
     194            $top_sources_rss_save = json_encode($top_sources_rss);
     195            update_option('expresscurate_top_sources_rss', $top_sources_rss_save);
     196        }
    192197        return $top_sources_rss;
    193198    }
    194 
    195 
    196 
    197 //
    198 //  public function get_curated_links2() {
    199 //    $curated_links = array();
    200 //    $date_after = '';
    201 //    $curated_links_rss = get_option('expresscurate_links_rss', '');
    202 //    if ($curated_links_rss) {
    203 //      $curated_links_rss = json_decode($curated_links_rss, true);
    204 //    } else {
    205 //      $curated_links_rss = array();
    206 //    }
    207 //    $top_sources_rss = get_option('expresscurate_top_sources_rss', '');
    208 //
    209 //    if ($top_sources_rss) {
    210 //      $top_sources_rss = json_decode($top_sources_rss, true);
    211 //      $date_after = strtotime($top_sources_rss['date']) . "&";
    212 //    } else {
    213 //      $top_sources_rss = array();
    214 //      $top_sources_rss['links'] = array();
    215 //    }
    216 //
    217 //    $curated_posts_query = new WP_Query("meta_key=_is_expresscurate&meta_value=1&posts_per_page=-1&" . $date_after . "order=DESC");
    218 //
    219 //    if ($curated_posts_query->have_posts()) {
    220 //      $i = 0;
    221 //      while ($curated_posts_query->have_posts()) {
    222 //        $curated_posts_query->the_post();
    223 //        $meta_values = get_post_meta(get_the_ID());
    224 //        // var_dump($meta_values);
    225 //        foreach ($meta_values as $key => $value) {
    226 //          if (preg_match('/_expresscurate_link_\d/', $key)) {
    227 //            if ($meta_values[$key][0]) {
    228 //              $normalised_url = expresscurate_normalise_url($meta_values[$key][0]);
    229 //              $domain = parse_url($normalised_url);
    230 //              if (preg_match('/(?P<subdomain>.<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain['host'], $regs)) {
    231 //                $curated_links[$i]['link'] = expresscurate_normalise_url($regs['domain']);
    232 //              } else {
    233 //                $curated_links[$i]['link'] = $normalised_url;
    234 //              }
    235 //              $curated_links[$i]['post_id'] = get_the_ID();
    236 //            }
    237 //            $i++;
    238 //          }
    239 //        }
    240 //      }
    241 //    }
    242 //    wp_reset_postdata();
    243 //
    244 //    foreach ($curated_links as $key => $top_link) {
    245 //     $rssUrl = $this->getRssUrl($top_link['link']);
    246 //       if($rssUrl){
    247 //           $top_link['link'] = $rssUrl;
    248 //       }
    249 //      $feed_url = false;
    250 //      if (isset($top_sources_rss['links'][$top_link['link']])) {
    251 //        $top_sources_rss['links'][$top_link['link']]['post_ids'][] = $top_link['post_id'];
    252 //        if (isset($curated_links_rss[$top_link['link']])) {
    253 //          $feed_status = 'rssStatusYes';
    254 //          $feed_url = $curated_links_rss[$top_link['link']]['feed_url'];
    255 //        } else {
    256 //          if (isset($top_sources_rss['links'][$top_link['link']]['feed_options']) && isset($top_sources_rss['links'][$top_link['link']]['feed_options']['checked']) && $top_sources_rss['links'][$top_link['link']]['feed_options']['checked'] == 1) {
    257 //            $feed_status = $top_sources_rss['links'][$top_link['link']]['feed_options']['feed_status'];
    258 //          } else {
    259 //            $feed_url = $this->getRssUrl($top_link['link']);
    260 //            if ($feed_url) {
    261 //              //if (1 == 1) {
    262 //              $feed_status = 'rssStatusAdd';
    263 //            } else {
    264 //              $feed_status = 'rssStatusNo';
    265 //            }
    266 //            $checked = 1;
    267 //          }
    268 //        }
    269 //        $checked = 1;
    270 //        $top_sources_rss['links'][$top_link['link']]['feed_options'] = array('feed_url' => $feed_url, 'feed_status' => $feed_status, 'checked' => 1, 'type' => 'feed');
    271 //      } else {
    272 //        if (isset($top_sources_rss['links'][$top_link['link']]['feed_options']) && isset($top_sources_rss['links'][$top_link['link']]['feed_options']['checked']) && $top_sources_rss['links'][$top_link['link']]['feed_options']['checked'] == 1) {
    273 //          $feed_status = $top_sources_rss['links'][$top_link['link']]['feed_options']['feed_status'];
    274 //        } else {
    275 //          if ($feed_url = $this->getRssUrl($top_link['link'])) {
    276 //            //if (1 == 1) {
    277 //            $feed_status = 'rssStatusAdd';
    278 //          } else {
    279 //            $feed_status = 'rssStatusNo';
    280 //          }
    281 //          $checked = 1;
    282 //        }
    283 //        $top_sources_rss['links'][$top_link['link']] = array('post_ids' => array($top_link['post_id']), 'feed_options' => array('feed_url' => $feed_url, 'feed_status' => $feed_status, 'checked' => $checked, 'type' => 'feed'));
    284 //      }
    285 //      $top_sources_rss['links'][$top_link['link']]['post_ids'] = array_unique($top_sources_rss['links'][$top_link['link']]['post_ids']);
    286 //      $top_sources_rss['links'][$top_link['link']]['post_count'] = count($top_sources_rss['links'][$top_link['link']]['post_ids']);
    287 //    }
    288 //
    289 //    @uasort($top_sources_rss['links'], array($this, "sort_by_count"));
    290 //    $top_sources_rss['date'] = date('Y-m-d H:i:s');
    291 //    $top_sources_rss_save = json_encode($top_sources_rss);
    292 //    update_option('expresscurate_top_sources_rss', $top_sources_rss_save);
    293 //    return $top_sources_rss;
    294 //  }
    295199
    296200    public function get_feed_list()
     
    326230        if(isset($url)) {
    327231            $lookup_url = "http://ajax.googleapis.com/ajax/services/feed/lookup?v=1.0&q=" . urlencode($url);
    328             $result = file_get_contents($lookup_url);
     232            //$result = file_get_contents($lookup_url);
     233            $htmlparser = new ExpressCurate_HtmlParser($lookup_url);
     234            $result = $htmlparser->download();
    329235
    330236            if (isset($result)) {
     
    347253
    348254        $lookup_url = "http://ajax.googleapis.com/ajax/services/feed/lookup?v=1.0&q=" . urlencode($url);
    349         $options = array('http' => array('user_agent' => USER_AGENT,' follow_location'=>1,'max_redirects'=>5,'request_fulluri '=>TRUE));
     255        /*$options = array('http' => array('user_agent' => USER_AGENT,'request_fulluri '=>TRUE));
    350256        if(preg_match("/(^https:\/\/)/i", $url)!=false){
    351257            $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false);
    352258        }
    353259        $context = stream_context_create($options);
    354         $res = file_get_contents($lookup_url,false,$context);
     260        $res = file_get_contents($lookup_url,false,$context);*/
     261        $htmlparser = new ExpressCurate_HtmlParser($lookup_url);
     262        $res = $htmlparser->download();
    355263        $result = json_decode($res);
    356264        if ($result && $result->responseData) {
     
    366274        $feed_array = array();
    367275        $data = $_REQUEST;
     276        $date = urldecode($date["date"]);
    368277        $curated_links_rss = get_option('expresscurate_links_rss', '');
    369278        if ($curated_links_rss) {
    370279            $curated_links_rss = json_decode($curated_links_rss, true);
    371280            $deleted_urls = array();
    372             if (!isset($data['date'])) {
     281            if (!isset($date)) {
    373282                $feed_content_deleted = get_option('expresscurate_feed_content_deleted', '');
    374283                if ($feed_content_deleted) {
     
    384293                foreach ($curated_links_rss as $url => $feed_url) {
    385294                    $lookup_url = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=" . urlencode($feed_url['feed_url']);
    386                     $result = json_decode(file_get_contents($lookup_url), true);
    387                     $this->collect_feed($result, $deleted_urls, $feed_array, 'feed', $data['date']);
     295                    //$result= json_decode(file_get_contents($lookup_url), true);
     296                    $htmlparser = new ExpressCurate_HtmlParser($lookup_url);
     297                    $res = $htmlparser->download();
     298                    $result = json_decode($res, true);
     299                    $this->collect_feed($result, $deleted_urls, $feed_array, 'feed', $date);
    388300                }
    389301            }
     
    393305            $feed_content = json_encode(array('date' => date('Y-m-d H:i:s'), 'content' => $feed_array));
    394306            update_option('expresscurate_feed_content', $feed_content);
    395 
    396         }
    397 
    398         return $feed_array;
    399     }
    400 
     307            return $feed_content;
     308        }
     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    }
    401324
    402325    public function filter_feeds_by_date(){
     
    406329        if(isset($data['date']) && !empty($feed_content['content'])){
    407330            foreach($feed_content['content'] as $link => $feed){
    408                 if($this->date_diff($feed['date'],$data['date'], false) >= 0){
     331                if((strtotime($feed['date']) - $data['date']) >= 0){
    409332                    $filtered_feeds[$link] = $feed;
    410333                }
     
    464387                $html_parser = new ExpressCurate_HtmlParser($link);
    465388                $keywords = $html_parser->analyzeKeywords();
    466                 $media = $html_parser->isMediaExists();
     389                $media = $html_parser->containsMedia();
    467390                $publishDate = isset($story['publishedDate']) ? $story['publishedDate'] : $story['date'];
    468391                $expressCurateDate = new ExpressCurate_Date();
     
    502425        $data = $_REQUEST;
    503426        if (isset($data['items'])) {
    504             $items = json_decode(stripslashes($data['items']), true);
     427            $items = $data['items'];
    505428            $result = array();
    506429            $feed_contents = get_option('expresscurate_feed_content', '');
     
    516439                }
    517440                foreach ($items as $item) {
    518                     $item = json_decode($item, true);
    519                     if (in_array($item['link'], $exists_url)) {
    520                         $feed_content_deleted[$item['link']] = $item;
    521                         unset($feed_contents['content'][$item['link']]);
     441                    if (in_array($item, $exists_url)) {
     442                        $feed_content_deleted[$item] = $item;
     443                        unset($feed_contents['content'][$item]);
    522444                    }
    523445                }
     
    543465        $data = $_REQUEST;
    544466        if (isset($data['items'])) {
    545 
    546467            $items = json_decode(stripslashes($data['items']), true);
    547468
     
    585506        $data = $_REQUEST;
    586507        $result = array();
    587         if (isset($data['url'])) {
    588             $bookmarks = get_option('expresscurate_bookmarks', '');
    589             if ($bookmarks) {
    590                 $bookmarks = json_decode($bookmarks, true);
    591             } else {
    592                 $bookmarks = array();
    593             }
    594             $exists_url = array();
    595             foreach ($bookmarks as $bookmark) {
    596                 $exists_url[] = $bookmark['link'];
    597             }
    598 
    599             $data['url'] = expresscurate_normalise_url($data['url'], true);
    600             if (!in_array($data['url'], $exists_url)) {
    601 
    602                 $contentManager = new ExpressCurate_ContentManager();
    603                 $article = $contentManager->get_article($data['url'], false);
    604                 if (isset($article['status']) && $article['status'] == 'success') {
    605                     $comment = isset($data['comment']) ? $data['comment'] : '';
    606                     $article['type'] = isset($data['type']) ? $data['type'] : 'user';
    607                     $current_user = wp_get_current_user();
    608                     $article['result']['user'] = $current_user->display_name;
    609                     $this->collect_bookmark($bookmarks, $article, $data['url'], $comment);
    610                     $result['status'] = 'success';
    611                     $result['result'] = $bookmarks[$data['url']];
    612                     $result['result']['curateLink']=base64_encode(urlencode($data['url']));
    613                     $bookmarks = json_encode($bookmarks);
    614                     update_option('expresscurate_bookmarks', $bookmarks);
     508        if(!ExpressCurate_HtmlParser::supportsDownload()){
     509            $result['status'] = 'error';
     510            $result['msg'] = 'You should activate either curl extension or allow_url_fopen setting.';
     511        }else {
     512            if (isset($data['url'])) {
     513                $bookmarks = get_option('expresscurate_bookmarks', '');
     514                $data_url = $data['url'];
     515                if ($bookmarks) {
     516                    $bookmarks = json_decode($bookmarks, true);
    615517                } else {
    616                     if (isset($article['status'])) {
    617                         $result['status'] = $article['status'];
    618                         $result['msg'] = $article['msg'];
     518                    $bookmarks = array();
     519                }
     520                $exists_url = array();
     521                foreach ($bookmarks as $bookmark) {
     522                    $exists_url[] = $bookmark['link'];
     523                }
     524
     525                $extracted_url = extract_google_feed_url($data_url, $bookmarks);
     526                if ($extracted_url) {
     527                    $data_url = $extracted_url;
     528                }
     529                $data_url = expresscurate_normalise_url($data_url, true);
     530
     531                if (!in_array($data_url, $exists_url)) {
     532
     533                    $contentManager = new ExpressCurate_ContentManager();
     534                    $article = $contentManager->get_article($data_url, false);
     535                    if (isset($article['status']) && $article['status'] == 'success') {
     536                        $comment = isset($data['comment']) ? $data['comment'] : '';
     537                        $article['type'] = isset($data['type']) ? $data['type'] : 'user';
     538                        $current_user = wp_get_current_user();
     539                        $article['result']['user'] = $current_user->display_name;
     540                        $this->collect_bookmark($bookmarks, $article, $data_url, $comment);
     541                        $result['status'] = 'success';
     542                        $result['result'] = $bookmarks[$data_url];
     543                        $result['result']['curateLink'] = base64_encode(urlencode($data_url));
     544                        $bookmarks = json_encode($bookmarks);
     545                        update_option('expresscurate_bookmarks', $bookmarks);
     546                    } else {
     547                        if (isset($article['status'])) {
     548                            $result['status'] = $article['status'];
     549                            $result['msg'] = $article['msg'];
     550                        } else {
     551                            $result['status'] = 'error';
     552                            $result['msg'] = 'Article does not exists.';
     553                        }
     554
     555                    }
     556                } else {
     557                    if (isset($data['comment'])) {
     558                        $bookmarks[$data['url']]['comment'] = $data['comment'];
     559                        $result['result'] = $bookmarks[$data_url];
     560                        $bookmarks = json_encode($bookmarks);
     561                        update_option('expresscurate_bookmarks', $bookmarks);
     562                        $result['status'] = 'success';
    619563                    } else {
    620564                        $result['status'] = 'error';
    621                         $result['msg'] = 'Article does not exists.';
    622                     }
    623 
    624                 }
    625             } else {
    626                 if (isset($data['comment'])) {
    627                     $bookmarks[$data['url']]['comment'] = $data['comment'];
    628                     $result['result'] = $bookmarks[$data['url']];
    629                     $bookmarks = json_encode($bookmarks);
    630                     update_option('expresscurate_bookmarks', $bookmarks);
    631                     $result['status'] = 'success';
    632                 } else {
    633                     $result['status'] = 'error';
    634                     $result['msg'] = 'This page is already bookmarked.';
    635                 }
    636             }
    637         } else {
    638             $result['status'] = 'error';
    639         }
    640 
     565                        $result['msg'] = 'This page is already bookmarked.';
     566                    }
     567                }
     568            } else {
     569                $result['status'] = 'error';
     570            }
     571        }
    641572        echo json_encode($result);
    642573        die;
     
    669600            $result['msg'] = 'Url is empty';
    670601        }
    671         echo json_encode($result);
     602        echo json_encode($result,JSON_UNESCAPED_SLASHES);
    672603        die;
    673604    }
  • expresscurate/trunk/ExpressCurate_HtmlParser.php

    r1115335 r1129694  
    1010
    1111class ExpressCurate_HtmlParser {
    12 
    13   private $dom;
     12  // resource details
    1413  private $url;
    1514  private $domain;
     
    1716  private $protocol;
    1817  private $path;
    19   private $html;
     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
    2032  private $title = null;
    2133  private $keywords = null;
    2234  private $description = null;
    23 
    24   public function __construct($url = false) {
    25     if($url){
    26         $this->url = $url;
    27         $path = parse_url($this->url, PHP_URL_PATH);
     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() {
     42        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'];
    2854        $lastof = strrpos($path, "/");
    2955        $path = substr($path, 0, $lastof);
    30         $this->domain = 'http://' . parse_url($this->url, PHP_URL_HOST);
    31         $this->path = 'http://' . parse_url($this->url, PHP_URL_HOST) . "/" . $path . "/";
    32         $this->fragment = parse_url($this->url, PHP_URL_FRAGMENT);
    33         $this->protocol = parse_url($this->url, PHP_URL_SCHEME);
    34     }
    35 
    36   }
    37 
    38   public function doRequest() {
    39     $this->html = $this->file_get_contents_utf8($this->url, false);
    40   }
    41 
    42   public function strip_tags_content($text, $tags = array(), $invert = FALSE) {
    43     $tags = array_unique($tags);
    44     if (is_array($tags) AND count($tags) > 0) {
    45       if ($invert == FALSE) {
    46         preg_match_all('@<(' . implode("|", $tags) . ')\b.*?>.*?</\1>@si', $text, $matches);
    47         $result = implode("", $matches[0]);
     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();
    4885      } else {
    49         $result = preg_replace('@<(?!(?:' . implode("|", $tags) . ')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
    50       }
    51     } elseif ($invert == FALSE) {
    52       return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
    53     }
    54     return $result;
    55   }
    56 
    57   private function getDescription() {
    58     // Get the 'content' attribute value in a <meta name="description" ... />
    59     $matches = array();
    60 
    61     // Search for <meta name="description" content="Buy my stuff" />
    62     preg_match('/<meta.*?name=("|\')description("|\').*?content=("|\')(.*?)("|\')/i', $this->html, $matches);
    63     if (count($matches) > 4) {
    64       return $matches[4];
    65     }
    66 
    67     // Order of attributes could be swapped around: <meta content="Buy my stuff" name="description" />
    68     preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')description("|\')/i', $this->html, $matches);
    69     if (count($matches) > 2) {
    70       return $matches[2];
    71     }
    72 
    73     // No match
    74     return null;
    75   }
    76 
     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     
     198//      if (self::supportsAsynch()) {
     199//          // setup the single curl
     200//          $ch = $this->createCURL($this->url);
     201//          $content = curl_exec($ch);
     202//          $this->dataHTTPStatus = curl_getinfo($this->asynchHandle, CURLINFO_HTTP_CODE);
     203//          $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
     204//          curl_close($ch);
     205//      } 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          }
     242//      }
     243
     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);
     284   
     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();
     440   
     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 
    77462  private function getKeywords() {
    78463    // Get the 'content' attribute value in a <meta name="keywords" ... />
     
    80465    $max_count = get_option("expresscurate_max_tags", 3);
    81466    // Search for <meta name="keywords" content="keyword1, keword2" />
    82     preg_match('/<meta.*?name=("|\')keywords("|\').*?content=("|\')(.*?)("|\')/i', $this->html, $matches);
     467    preg_match('/<meta.*?name=("|\')keywords("|\').*?content=("|\')(.*?)("|\')/i', $this->data, $matches);
    83468    if (count($matches) > 4) {
    84469      return array_filter(explode(",", trim($matches[4])));
    85       //return array_slice(array_filter(explode(", ", trim($matches[4]))), 0, $max_count);
    86     }
    87 
    88 // Order of attributes could be swapped around: <meta content="keyword1, keword2" name="keywords" />
    89     preg_match('/<meta.*?content=("|\')(.*?)("|\').*?name=("|\')keywords("|\')/i', $this->html, $matches);
     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);
    90474    if (count($matches) > 2) {
    91       return array_filter(explode(",", trim($matches[2])));
    92 //return array_slice(array_filter(explode(", ", trim($matches[2]))), 0, $max_count);
    93     }
    94 
    95 // No match
     475        return array_filter(explode(",", trim($matches[2])));
     476    }
     477
     478    // No match
    96479    return null;
    97480  }
    98 
    99   private function getTitle() {
    100     $this->dom = new DOMDocument();
    101     @$this->dom->loadHTML(mb_convert_encoding($this->html, 'HTML-ENTITIES', "UTF-8"));
    102     $this->dom->encoding = 'UTF-8';
    103     $xpath = new DOMXPath($this->dom);
    104     $title = $xpath->query('//title')->item(0)->nodeValue;
    105 //file_put_contents ('text.txt' , $title);
    106 //$title = mb_convert_encoding($title, 'HTML-ENTITIES', "UTF-8");
    107 //iconv(mb_detect_encoding($title, mb_detect_order(), true), "UTF-8", $title);
    108     return $title;
    109   }
    110 
    111   public function getHtml() {
    112     $this->doRequest();
    113     mb_convert_encoding($this->html, 'HTML-ENTITIES', "UTF-8");
    114     if (strlen($this->html) > 3) {
    115       $this->title = $this->getTitle();
    116       $this->keywords = $this->getKeywords();
    117       $this->description = $this->getDescription();
    118       $this->cleanHtml();
    119       $result = $this->getElementsByTags();
    120       return $result;
    121     }
    122   }
    123 
    124   public function cleanHtml() {
     481 
     482  private function getDescription() {
     483    // Get the 'content' attribute value in a <meta name="description" ... />
    125484    $matches = array();
    126     $this->html = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $this->html);
    127 //$this->html = preg_replace('/[\r|\n]+/msi', '', $this->html);
    128     $this->html = preg_replace('/<--[\S\s]*?-->/msi', '', $this->html);
    129     /*$this->html = preg_replace('/<noscript[^>]*>[\S\s]*?' .
    130             '<\/noscript>/msi', '', $this->html);*/
    131     $this->html = preg_replace('/(<noscript[^>]*>|<\/noscript>)/msi', '', $this->html);
    132     $this->html = preg_replace('~>\s+<~', '><', $this->html);
    133     $this->html = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $this->html);
    134     $this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', "UTF-8");
     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;
    135500  }
    136501
    137502  private function getElementsByTags() {
    138     $this->html = preg_replace('/^.*(?=<html>)/i', '', $this->html);
    139     $this->html = str_replace("\0", " ",$this->html);
    140     $this->dom = new DOMDocument();
    141     @$this->dom->loadHTML($this->html);
    142 
    143     $this->removeElementsByTagName('script', $this->dom);
    144     $this->removeElementsByTagName('style', $this->dom);
    145     $this->removeElementsByTagName('link', $this->dom);
    146 
    147     $this->dom->saveHtml();
     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   
    148507    $result_images = array();
    149508    $result_paragraphs = array();
     
    151510    $result_h2 = '';
    152511    $result_h3 = '';
    153     $xpath = new DOMXPath($this->dom);
    154     $imgTags = $xpath->query("//img");
     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");
    155515    $i = 0;
    156516    foreach ($imgTags as $t) {
     
    160520          $src = $src;
    161521        } else if (strpos($src, '//') === 0) {
    162           if(isset($this->fragment)){
     522          if(isset($this->fragment)) {
    163523              $src = $this->fragment . $src;
    164524          }
    165525          else{
    166               $src = $this->protocol.":" . $src;
     526              $src = $this->protocol . ":" . $src;
    167527          }
    168528        } elseif (strpos($src, '/') === 0) {
     
    171531          $src = $this->path . $src;
    172532        }
     533
    173534        $src = preg_replace('%([^:])([/]{2,})%', '\\1/', $src);
    174535
     
    180541      $t->parentNode->removeChild($t);
    181542    }
    182 //get H1
    183     $h1Tag = $xpath->query('//h1');
     543    //get H1
     544    $h1Tag = $this->xpath->query('//h1');
    184545    foreach ($h1Tag as $h1) {
    185546      if (strlen($h1->nodeValue) > 3) {
    186         $result_h1 .= htmlentities($h1->nodeValue, ENT_QUOTES, "UTF-8") . "\n";
     547        $result_h1 .= $h1->nodeValue . "\n";
    187548      }
    188549      $h1->parentNode->removeChild($h1);
    189550    }
    190 //get H2
    191     $h2Tag = $xpath->query('//h2');
     551    //get H2
     552    $h2Tag = $this->xpath->query('//h2');
    192553    foreach ($h2Tag as $h2) {
    193554      if (strlen($h2->nodeValue) > 3) {
    194         $result_h2 .= htmlentities($h2->nodeValue, ENT_QUOTES, "UTF-8") . "\n";
     555        $result_h2 .= $h2->nodeValue . "\n";
    195556      }
    196557      $h2->parentNode->removeChild($h2);
    197558    }
    198 //get H3
    199     $h3Tag = $xpath->query('//h3');
     559    //get H3
     560    $h3Tag = $this->xpath->query('//h3');
    200561    foreach ($h3Tag as $h3) {
    201562      if (strlen($h3->nodeValue) > 3) {
    202         $result_h3 .= htmlentities($h3->nodeValue, ENT_QUOTES, "UTF-8") . "\n";
     563        $result_h3 .= $h3->nodeValue . "\n";
    203564      }
    204565      $h3->parentNode->removeChild($h3);
    205566    }
    206 //get text
     567    //get text
    207568    $i = 0;
    208     $articleTags = $xpath->query('/html/body/article');
     569    $articleTags = $this->xpath->query('/html/body/article');
    209570    foreach ($articleTags as $t) {
    210       //$result_paragraphs[] = strip_tags($this->escapeJsonString(trim($t->nodeValue)));
    211       $result_paragraphs[$i]['value'] = strip_tags(htmlentities(trim($t->nodeValue), ENT_QUOTES, "UTF-8"));
     571      $result_paragraphs[$i]['value'] = strip_tags(trim($t->nodeValue));
    212572      $result_paragraphs[$i]['tag'] = 'article';
    213573      $t->parentNode->removeChild($t);
     
    216576
    217577
    218     $textTags = $xpath->query('/html/body//text()');
     578    $textTags = $this->xpath->query('/html/body//text()');
    219579
    220580    foreach ($textTags as $t) {
    221581      if ($t->length > 15 && $t->parentNode->tagName != 'a' && $t->parentNode->tagName != 'h1' && $t->parentNode->tagName != 'h2' && $t->parentNode->tagName != 'h3') {
    222         //$result_paragraphs[] = strip_tags($this->escapeJsonString(trim($t->nodeValue)));
    223582        if ($t->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->nodeName == "blockquote" || $t->parentNode->parentNode->parentNode->nodeName == "blockquote") {
    224583          if ($t->parentNode->nodeName == "blockquote") {
    225             $result_paragraphs[$i]['value'] = strip_tags(htmlentities($t->parentNode->nodeValue, ENT_QUOTES, "UTF-8"));
     584            $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->nodeValue);
    226585          } elseif ($t->parentNode->parentNode && $t->parentNode->parentNode->nodeName == "blockquote") {
    227             $result_paragraphs[$i]['value'] = strip_tags(htmlentities($t->parentNode->parentNode->nodeValue, ENT_QUOTES, "UTF-8"));
     586            $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->nodeValue);
    228587          } elseif ($t->parentNode->parentNode->parentNode && $t->parentNode->parentNode->parentNode->nodeName == "blockquote") {
    229             $result_paragraphs[$i]['value'] = strip_tags(htmlentities($t->parentNode->parentNode->parentNode->nodeValue, ENT_QUOTES, "UTF-8"));
     588            $result_paragraphs[$i]['value'] = strip_tags($t->parentNode->parentNode->parentNode->nodeValue);
    230589          }
    231590          $result_paragraphs[$i]['tag'] = "blockquote";
    232591        } else {
    233           $result_paragraphs[$i]['value'] = strip_tags(htmlentities($t->nodeValue, ENT_QUOTES, "UTF-8"));
     592          $result_paragraphs[$i]['value'] = strip_tags($t->nodeValue);
    234593          $result_paragraphs[$i]['tag'] = $t->parentNode->nodeName;
    235594        }
     
    239598    //author
    240599    $article_author = '';
    241     $author = $xpath->query('//*[@rel="author"][1]')->item(0);
     600    $author = $this->xpath->query('//*[@rel="author"][1]')->item(0);
    242601    if ($author) {
    243602      $article_author = $author->nodeValue;
     
    245604    //date
    246605    $article_date = '';
    247     $date = $xpath->query('//*[@datetime][1]')->item(0);
     606    $date = $this->xpath->query('//*[@datetime][1]')->item(0);
    248607    if ($date) {
    249608      $article_date = $date->nodeValue;
     
    251610
    252611
    253 //smart tags
     612    //smart tags
    254613    $max_count = get_option("expresscurate_max_tags", 3);
    255614    $smart_tags = array();
     
    260619      foreach ($defined_tags as $tag) {
    261620        $tag = trim($tag);
    262         $count = $this->countMathes($tag);
     621        $count = $this->countMatches($tag);
    263622        if ($count > 0) {
    264623          $smart_tags[$tag] = $count;
     
    269628    if (count($this->keywords)) {
    270629      foreach ($this->keywords as $key => $keyword) {
    271         $count = $this->countMathes($key);
     630        $count = $this->countMatches($key);
    272631        if ($count > 0) {
    273632          $smart_tags[$keyword] = $count;
     
    280639      $smart_tags = array_slice(array_keys(array_reverse($smart_tags)), 0, $max_count);
    281640    }
     641   
    282642    $result_paragraphs_unique = $this->arrayUnique($result_paragraphs);
    283     $media = $this->isMediaExists();
    284     $result = array('title' => $this->title, 'headings' => array('h1' => $result_h1, 'h2' => $result_h2, 'h3' => $result_h3), 'metas' => array('description' => $this->description, 'keywords' => $smart_tags), 'images' => $result_images, 'media'=>$media,  'paragraphs' => $result_paragraphs_unique, 'author' => $article_author, 'date' => $article_date, 'domain' => $this->domain);
     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);
    285655    $data = array('status' => 'success', 'result' => $result);
    286656    return $data;
    287657  }
    288658
    289   private function countMathes($keyword) {
    290     $total_occurrence = 0;
    291     $tag_in_title = array();
    292     $tag_in_content = array();
    293     preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->title, $tag_in_title);
    294     preg_match_all("/(?<!\w)(?=[^>]*(<|$))" . $keyword . "/i", $this->html, $tag_in_content);
    295     $total_occurrence = count($tag_in_title[0]) + count($tag_in_content[0]);
    296     return $total_occurrence;
    297   }
    298 
    299   public function file_get_contents_utf8($url, $get_http_status = false, $set_utf8 = true) {
    300     $content = '';
    301     $charset = '';
    302     $utf8 = false;
    303     //$user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36';
    304     $file_get_enabled = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
    305     if ($file_get_enabled) {
    306         /*$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));*/
    307         if(preg_match("/(https?:\/\/www.google.com\/url)/",$url)) {
    308             $parsed_url= parse_url($url);
    309             $url_query = explode("&",$parsed_url['query']);
    310             foreach($url_query as $param) {
    311                 if(strpos($param, 'url=') === 0) {
    312                     $url = str_replace("url=", "", $param);
    313                     $url = urldecode($url);
    314                     break;
    315                 }
    316             }
    317         }
    318         $options = array('http' => array('user_agent' => USER_AGENT,' follow_location'=>1,'max_redirects'=>5,'request_fulluri '=>TRUE));
    319         if(preg_match("/(^https:\/\/)/i", $url)!=false){
    320             $options['ssl']=array('verify_peer'=> false,"verify_peer_name"=>false);
    321         }
    322         $context = stream_context_create($options);
    323       $content = @file_get_contents($url, false, $context);
    324        // $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    325       $http_status = $http_response_header;
    326 
    327       if(!empty($http_response_header)) {
    328           foreach ($http_response_header as $header) {
    329               if (substr(strtolower($header), 0, 13) == "content-type:") {
    330                   if (count(explode(";", $header)) > 1) {
    331                       list($contentType, $charset) = explode(";", $header);
    332                   }
    333               }
    334           }
    335       }
    336 
    337       $headers = headers_list();
    338       // get the content type header
    339       foreach ($headers as $header) {
    340         if (substr(strtolower($header), 0, 13) == "content-type:") {
    341           list($contentType, $charset) = explode(";", trim(substr($header, 14), 2));
    342           if (strtolower(trim($charset)) == "charset=utf-8") {
    343             $utf8 = true;
    344           }
    345         }
    346       }
    347       if ($charset && strpos(strtolower($charset), 'utf-8')) {
    348         $utf8 = true;
    349       } else {
    350         $charset = mb_detect_encoding($content);
    351         if (strpos(strtolower($charset), 'utf-8')) {
    352           $utf8 = true;
    353         }
    354       }
    355       if (!$utf8 && $set_utf8) {
    356         $content = utf8_encode($content);
    357       }
    358     } elseif (is_callable('curl_init')) {
    359       $ch = curl_init($url);
    360       //curl_setopt($ch, CURLOPT_HEADER, 1);
    361       curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    362       curl_setopt($ch, CURLOPT_USERAGENT, USER_AGENT);
    363       curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: text/xml;charset=\"utf-8\""));
    364       curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    365       curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    366       curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
    367       $content = curl_exec($ch);
    368       $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    369       curl_close($ch);
    370     } else {
    371       $data = array('status' => 'warning', 'msg' => 'Content from this page cannot be loaded.  Please enable \"allow_url_open\" in php.ini.');
    372       echo json_encode($data);
    373       die();
    374     }
    375     if (!$get_http_status) {
    376       return $content;
    377     } else {
    378       return array('content' => $content, 'http_status' => $http_status);
    379     }
     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;
    380667  }
    381668
     
    404691  }
    405692
    406   private function removeElementsByTagName($tagName, $document) {
    407     $nodeList = $document->getElementsByTagName($tagName);
    408     for ($nodeIdx = $nodeList->length; --$nodeIdx >= 0;) {
    409       $node = $nodeList->item($nodeIdx);
    410       $node->parentNode->removeChild($node);
    411     }
    412   }
    413 
    414   public function analyzeKeywords(){
     693  public function analyzeKeywords() {
    415694      $keywordsString =  get_option('expresscurate_defined_tags');
    416       $blogKeywords = !empty($keywordsString)? explode(', ', $keywordsString) : array();
    417       $this->doRequest();
    418       mb_convert_encoding($this->html, 'HTML-ENTITIES', "UTF-8");
    419       $dom = new DOMDocument('1.0', 'UTF-8');
    420 
    421       @$dom->loadHTML($this->html);
    422       $finder = new DomXPath($dom);
    423       $title = $dom->getElementsByTagName('h1')->item(0)->nodeValue;
     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;
    424702      $titleArray = preg_split('/\s+/u', $title);
    425703
    426       $this->removeElementsByTagName('script', $dom);
    427       $this->removeElementsByTagName('style', $dom);
    428       $this->removeElementsByTagName('link', $dom);
    429 
    430       $article = strip_tags($dom->getElementsByTagName('article')->item(0)->nodeValue);
    431       if(empty($article)){
    432           $article = strip_tags($finder->query("//*[contains(@class, 'hentry')]")->item(0)->nodeValue);
    433       }
    434 
    435       if(empty($article)){
    436           $article = strip_tags($finder->query("//*[contains(@itemtype, 'http://schema.org/Article')]")->item(0)->nodeValue);
    437       }
    438 
    439       if(empty($article)){
    440           $article = strip_tags($finder->query("//*[contains(@itemtype, 'http://schema.org/TechArticle')]")->item(0)->nodeValue);
    441       }
    442 
    443       if(empty($article)){
    444           $article = strip_tags($finder->query("//*[contains(@itemtype, 'http://schema.org/ScholarlyArticle')]")->item(0)->nodeValue);
    445       }
    446 
    447       if(empty($article)){
    448           $article = strip_tags($dom->getElementsByTagName('body')->item(0)->nodeValue);
    449       }
    450 
    451       $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);
    452       $articleFiltered  =  preg_replace('/\p{P}+/u',' ',$articleFiltered);
     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);
    453707      $articleArray = preg_split('/\s+/u', $articleFiltered);
    454708      $articleWordsCount = count($articleArray);
     709
     710      $result = array();
    455711
    456712      foreach($blogKeywords as $keyword) {
    457713          $count = 0;
    458714          $inTitle = 'No';
    459          /* foreach($articleArray as $word){
    460               if (mb_strtolower($word) == mb_strtolower($keyword)){
    461                $count++;
    462               }
    463           }*/
    464           if (in_array(mb_strtolower($keyword), $articleArray)){
     715
     716          if (in_array(mb_strtolower($keyword), $articleArray)) {
    465717              $count++;
    466718          }
    467           foreach($titleArray as $titleWord){
    468               if (mb_strtolower($titleWord) == mb_strtolower($keyword)){
     719          foreach($titleArray as $titleWord) {
     720              if (mb_strtolower($titleWord) == mb_strtolower($keyword)) {
    469721                  $inTitle = 'Yes';
    470722                  break;
    471723              }
    472724          }
    473             if($count !== 0){
    474                 $this->keywords[$keyword] = array('percent' => round($count/$articleWordsCount, 4), 'title'=>$inTitle);
    475             }
    476 
    477       }
    478 
    479       return $this->keywords;
    480   }
    481 
    482    public function isMediaExists(){
    483        $dom = new DOMDocument('1.0', 'UTF-8');
    484        @$dom->loadHTML($this->html);
    485        $xpath = new DomXPath($dom);
    486        $this->removeElementsByTagName('script', $dom);
    487        $this->removeElementsByTagName('style', $dom);
    488        $this->removeElementsByTagName('link', $dom);
    489        $imgTags = $xpath->query("//img");
     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");
    490737       $img_array = array();
    491738       foreach ($imgTags as $t) {
     
    493740           $img_array[] = $src;
    494741       }
    495        $obj = $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'))]");
     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'))]");
    496743       $videoArrays = array();
    497        foreach($obj as $objs){
     744       foreach($obj as $objs) {
    498745           array_push($videoArrays,$objs->getAttribute('src'));
    499746       }
     
    501748       return $mediaTags;
    502749   }
    503 
    504     function getTextBetweenTags($tag, $html, $strict=0)
    505     {
    506         /*** a new dom object ***/
    507 //        $dom = new domDocument;
    508         $dom = new DOMDocument('1.0', 'UTF-8');
    509         $dom->strictErrorChecking = FALSE ;
    510         $html = mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' );
    511         libxml_use_internal_errors(true);
    512         /*** load the html into the object ***/
    513         if($strict==1) {
    514             @$dom->loadXML($html);
    515             $loadHTML = true;
    516         } else {
    517             $dom->loadHTML($html);
    518             if(count(libxml_get_errors())>0){
    519                 update_option("expresscurate_html_error","Unable to load malstructered HTML. Please edit html structure and save again");
    520             }
    521             else {
    522                 $loadHTML = true;
    523                 update_option("expresscurate_html_error",'');
    524             }
    525 
    526         }
    527 
    528         if($loadHTML){
    529             /*** discard white space ***/
    530             $dom->preserveWhiteSpace = false;
    531 
    532             /*** the tag by its tag name ***/
    533             $content = $dom->getElementsByTagname($tag);
    534 
    535             /*** the array to return ***/
    536             $out = array();
    537             foreach ($content as $item) {
    538                 /*** add node value to the out array ***/
    539                 $out[] = $item->nodeValue;
    540             }
    541             /*** return the results ***/
    542             return $out;
    543         }
    544     }
    545 
    546 
    547750}
    548751
  • expresscurate/trunk/ExpressCurate_Keywords.php

    r1115335 r1129694  
    99 */
    1010
    11 class ExpressCurate_Keywords {
     11class ExpressCurate_Keywords
     12{
    1213
    1314
    1415    private static $instance;
    1516
    16     function __construct() {
     17    function __construct()
     18    {
    1719        // action shall be added from actions controller
    1820    }
    1921
    20     public static function getInstance() {
    21         if ( ! ( self::$instance instanceof self ) ) {
     22    public static function getInstance()
     23    {
     24        if (!(self::$instance instanceof self)) {
    2225            self::$instance = new self();
    2326        }
     
    2629    }
    2730
    28   public function getKeywords() {
    29     $definedKeyWords = get_option('expresscurate_defined_tags', true);
    30     if (empty($definedKeyWords)) {
    31       return false;
    32     } else {
    33       $definedKeywordsArray = explode(',', mb_strtolower($definedKeyWords,"UTF-8"));
    34       return $definedKeywordsArray;
    35     }
    36   }
    37 
    38   public function get_words($args = false, $new_post = false) {
    39     $stop_words = array('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');
    40     $post_text = '';
    41     $post_arr = array();
    42     $post_titles = '';
    43     if ($args === false && $new_post === false) {
    44       $posts = array();
    45 
    46        /* $publishedPostCount = wp_count_posts()->publish;
    47         for ($i = 0; $i < ceil($publishedPostCount / 200); $i++) {
    48             $args = array('status' => 'published', 'numberposts' => 200, 'offset' => $i * 200);
    49             $posts = array_merge($posts, get_posts($args)) ;
    50         }*/
    51 
    52         $posts = $this->post_handling_by_portion('posts');
    53     }
    54     if (isset($args['id'])) {
    55       $post = get_post($args['id']);
    56       $post_text .= $post->post_content;
    57       $post_titles .= $post->post_title;
    58     } else {
    59       if ($new_post === false) {
    60         $posts = get_posts($args);
    61         for ($i = 0; $i < count($posts); $i++) {
    62           $post_text .= $posts[$i]->post_content;
    63           $post_titles .= $posts[$i]->post_title;
    64           $post_arr[$i] = $posts[$i]->post_content;
    65         }
    66       } else {
    67         $post_text = $new_post['content'];
    68         $post_titles = $new_post['title'];
    69       }
    70     }
    71       $post_text = strip_tags($post_text);
    72       $post_text = preg_replace('/&(amp;)?#?[a-z0-9]+;/', '-', $post_text);
    73       $post_text = preg_replace('/\b(' . implode('|', $stop_words) . ')\b/iu', '', $post_text);
    74       $post_text = preg_replace('/\b[^\s]{1,2}\b/iu', '', $post_text);
    75       $post_text = preg_replace("/[\",.':;\\-\\=\\+\\)\\?\\!\\&\\(\\}\\{\\[\\]\\@]/u", "", $post_text);
    76       $post_words = array_count_values(preg_split('~[^\p{L}\p{N}\']+~u',$post_text));
    77       unset($post_words['']);
    78       $post_words = $this->array_map_keys('mb_strtolower', $post_words,'UTF-8');
    79       $post_words = array_filter($post_words);
     31    public function getKeywords()
     32    {
     33        $definedKeyWords = get_option('expresscurate_defined_tags', true);
     34        if (empty($definedKeyWords)) {
     35            return false;
     36        } else {
     37            $definedKeywordsArray = explode(',', mb_strtolower($definedKeyWords, "UTF-8"));
     38            return $definedKeywordsArray;
     39        }
     40    }
     41
     42    public function get_words($args = false, $new_post = false)
     43    {
     44        $stop_words = array('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');
     45        $post_text = '';
     46        $post_arr = array();
     47        $post_titles = '';
     48        if ($args === false && $new_post === false) {
     49            $posts = array();
     50
     51            /* $publishedPostCount = wp_count_posts()->publish;
     52             for ($i = 0; $i < ceil($publishedPostCount / 200); $i++) {
     53                 $args = array('status' => 'published', 'numberposts' => 200, 'offset' => $i * 200);
     54                 $posts = array_merge($posts, get_posts($args)) ;
     55             }*/
     56
     57            $posts = $this->post_handling_by_portion('posts');
     58        }
     59        if (isset($args['id'])) {
     60            $post = get_post($args['id']);
     61            $post_text .= $post->post_content;
     62            $post_titles .= $post->post_title;
     63        } else {
     64            if ($new_post === false) {
     65                $posts = get_posts($args);
     66                for ($i = 0; $i < count($posts); $i++) {
     67                    $post_text .= $posts[$i]->post_content;
     68                    $post_titles .= $posts[$i]->post_title;
     69                    $post_arr[$i] = $posts[$i]->post_content;
     70                }
     71            } else {
     72                $post_text = $new_post['content'];
     73                $post_titles = $new_post['title'];
     74            }
     75        }
     76        $post_text = strip_tags($post_text);
     77        $post_text = preg_replace('/&(amp;)?#?[a-z0-9]+;/', '-', $post_text);
     78        $post_text = preg_replace('/\b(' . implode('|', $stop_words) . ')\b/iu', '', $post_text);
     79        $post_text = preg_replace('/\b[^\s]{1,2}\b/iu', '', $post_text);
     80        $post_text = preg_replace("/[\",.':;\\-\\=\\+\\)\\?\\!\\&\\(\\}\\{\\[\\]\\@]/u", "", $post_text);
     81        $post_words = array_count_values(preg_split('~[^\p{L}\p{N}\']+~u', $post_text));
     82        unset($post_words['']);
     83        $post_words = $this->array_map_keys('mb_strtolower', $post_words, 'UTF-8');
     84        $post_words = array_filter($post_words);
    8085
    8186//      unset($post_words[null]);
    8287//      unset($post_words[' ']);
    8388//      unset($post_words['\'']);
    84 /*      unset($post_words['-']);
    85       unset($post_words['nbsp']);*/
    86       arsort($post_words);
    87 
    88       $total = array_sum($post_words);
    89     $result = array('titles' => $post_titles, 'content' => $post_text, 'posts' => $post_arr, 'words' => $post_words, 'total' => $total, 'stopwords' => $stop_words);
    90     return $result;
    91   }
    92 
    93   public function add_keyword($keyword, $get_stats = false) {
    94 
    95     $defined_tags_arr = array();
    96     $keywords = array();
    97     if(isset($_REQUEST['keywords'])) {
    98       $keywords = explode(",", $_REQUEST['keywords']);
    99     }
    100     $get_stats = $_REQUEST['get_stats'];
    101     $defined_tags = get_option("expresscurate_defined_tags", '');
    102     if ($defined_tags) {
    103       $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
    104       unset($defined_tags_arr['']);
    105     }
    106     if (count($keywords) > 0) {
    107 
    108       foreach ($keywords as $key => $keyword) {
    109         $keyword = str_replace('"', '', stripslashes(trim($keyword)));
    110         $keyword = str_replace("\\\"", '', $keyword);
    111         $keyword = str_replace("\\'", '', $keyword);
    112         $keyword = str_replace("\\\\", '', $keyword);       
    113         if (strlen($keyword) > 2) {
    114           if (preg_grep("/\b" . $keyword . "\b\w+/iu", $defined_tags_arr)) {
    115             $result = array('status' => "warning", 'msg' => __($keyword . ' is already defined'));
    116           } else {
     89        /*      unset($post_words['-']);
     90              unset($post_words['nbsp']);*/
     91        arsort($post_words);
     92
     93        $total = array_sum($post_words);
     94        $result = array('titles' => $post_titles, 'content' => $post_text, 'posts' => $post_arr, 'words' => $post_words, 'total' => $total, 'stopwords' => $stop_words);
     95        return $result;
     96    }
     97
     98    public function add_keyword($keyword, $get_stats = false)
     99    {
     100
     101        $defined_tags_arr = array();
     102        $keywords = array();
     103        if (isset($_REQUEST['keywords'])) {
     104            $keywords = explode(",", $_REQUEST['keywords']);
     105        }
     106        $get_stats = $_REQUEST['get_stats'];
     107        $defined_tags = get_option("expresscurate_defined_tags", '');
     108        if ($defined_tags) {
     109            $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
     110            unset($defined_tags_arr['']);
     111        }
     112        if (count($keywords) > 0) {
     113
     114            foreach ($keywords as $key => $keyword) {
     115                $keyword = str_replace('"', '', stripslashes(trim($keyword)));
     116                $keyword = str_replace("\\\"", '', $keyword);
     117                $keyword = str_replace("\\'", '', $keyword);
     118                $keyword = str_replace("\\\\", '', $keyword);
     119                if (strlen($keyword) > 2) {
     120                    if (preg_grep("/\b" . $keyword . "\b\w+/iu", $defined_tags_arr)) {
     121                        $result = array('status' => "warning", 'msg' => __($keyword . ' is already defined'));
     122                    } else {
     123                        if ($defined_tags) {
     124
     125                            $defined_tags .= ", " . $keyword;
     126                        } else {
     127                            $defined_tags = $keyword;
     128                        }
     129                        $defined_tags = str_replace(', ,', ',', $defined_tags);
     130                        update_option('expresscurate_defined_tags', $defined_tags);
     131                    }
     132                } else {
     133                    unset($keywords[$key]);
     134                }
     135            }
     136            if ($get_stats == true) {
     137                $stats = $this->getKeywordStats();
     138                $result = array('status' => "success", 'stats' => $stats);
     139            } else {
     140                $result = array('status' => "success");
     141            }
     142        } else {
     143            $result = array('status' => "warning", 'msg' => __('Calculation Error. Please try refreshing this web page.  If the problem persists, contact us'));
     144        }
     145        echo json_encode($result);
     146        die();
     147    }
     148
     149    public function get_post_keyword_stats($keyword, $post_id = false)
     150    {
     151        $args = false;
     152
     153        if ($_REQUEST) {
     154            $keyword = $_REQUEST['keyword'];
     155            if (strpos($keyword, ",")) {
     156                $keywords = explode(',', $keyword);
     157            }
     158            $post_id = (isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : false);
     159        }
     160        if ($post_id) {
     161            $args = array('id' => $post_id);
     162        }
     163        if (count(@$keywords) > 0) {
     164            $stats = $this->get_stats($keywords, $args, false, false);
     165        } else {
     166            $stats = $this->get_stats(array($keyword), $args, false, false);
     167        }
     168        $result = array('status' => "success", 'stats' => $stats);
     169        echo json_encode($result);
     170        die();
     171    }
     172
     173    public function delete_keyword()
     174    {
     175        if ($_REQUEST) {
     176            $keyword = trim($_REQUEST['keyword']);
     177
     178            $defined_tags = get_option("expresscurate_defined_tags", '');
    117179            if ($defined_tags) {
    118 
    119               $defined_tags .= ", " . $keyword;
    120             } else {
    121               $defined_tags = $keyword;
    122             }
    123             $defined_tags = str_replace(', ,', ',', $defined_tags);
    124             update_option('expresscurate_defined_tags', $defined_tags);
    125           }
    126         } else {
    127           unset($keywords[$key]);
    128         }
    129       }
    130       if ($get_stats == true) {
    131         $stats = $this->getKeywordStats();
    132         $result = array('status' => "success", 'stats' => $stats);
    133       } else {
    134         $result = array('status' => "success");
    135       }
    136     } else {
    137       $result = array('status' => "warning", 'msg' => __('Calculation Error. Please try refreshing this web page.  If the problem persists, contact us'));
    138     }
    139     echo json_encode($result);
    140     die();
    141   }
    142 
    143   public function get_post_keyword_stats($keyword, $post_id = false) {
    144     $args = false;
    145 
    146     if ($_REQUEST) {
    147       $keyword = $_REQUEST['keyword'];
    148       if (strpos($keyword, ",")) {
    149         $keywords = explode(',', $keyword);
    150       }
    151       $post_id = (isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : false);
    152     }
    153     if ($post_id) {
    154       $args = array('id' => $post_id);
    155     }
    156     if (count(@$keywords) > 0) {
    157       $stats = $this->get_stats($keywords, $args, false, false);
    158     } else {
    159       $stats = $this->get_stats(array($keyword), $args, false, false);
    160     }
    161     $result = array('status' => "success", 'stats' => $stats);
    162     echo json_encode($result);
    163     die();
    164   }
    165 
    166   public function delete_keyword() {
    167     if ($_REQUEST) {
    168       $keyword = trim($_REQUEST['keyword']);
    169 
    170       $defined_tags = get_option("expresscurate_defined_tags", '');
    171       if ($defined_tags) {
    172         $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
    173       }
    174       if (($key = array_search($keyword, $defined_tags_arr)) !== false) {
    175         unset($defined_tags_arr[$key]);
    176       }
    177       $filtered_tags = implode(', ', $defined_tags_arr);
    178       update_option('expresscurate_defined_tags', $filtered_tags);
    179       $result = array('status' => "success");
    180     } else {
    181       $result = array('status' => "error", 'msg' => "Calculation Error. Please try refreshing this web page.  If the problem persists, contact us");
    182     }
    183     echo json_encode($result);
    184     die();
    185   }
    186 
    187     public function get_stats($keywords = array(), $args = false, $post_content = false, $get_posts_count = false) {
     180                $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
     181            }
     182            if (($key = array_search($keyword, $defined_tags_arr)) !== false) {
     183                unset($defined_tags_arr[$key]);
     184            }
     185            $filtered_tags = implode(', ', $defined_tags_arr);
     186            update_option('expresscurate_defined_tags', $filtered_tags);
     187            $result = array('status' => "success");
     188        } else {
     189            $result = array('status' => "error", 'msg' => "Calculation Error. Please try refreshing this web page.  If the problem persists, contact us");
     190        }
     191        echo json_encode($result);
     192        die();
     193    }
     194
     195    public function get_stats($keywords = array(), $args = false, $post_content = false, $get_posts_count = false)
     196    {
    188197        if (!$post_content) {
    189198            $post_content = $this->get_words($args);
     
    209218                $keyword_in[$keyword]['title'] = 0;
    210219                if ($post_content['total'] !== 0) {
    211                     $keyword_in[$keyword]['percent'] = round(( $keyword_in[$keyword]['count'] / $post_content['total']) * 100, 2);
     220                    $keyword_in[$keyword]['percent'] = round(($keyword_in[$keyword]['count'] / $post_content['total']) * 100, 2);
    212221                    $keyword_in[$keyword]['posts_count'] = 0;
    213222                    if ($get_posts_count) {
     
    225234                $count = 0;
    226235                preg_replace('/\b' . $keyword . '\b/iu', '', $post_content['titles'], -1, $count);
    227                 $keyword_in[$keyword]['title_matches']  = $count;
     236                $keyword_in[$keyword]['title_matches'] = $count;
    228237                if ($count > 0) {
    229238                    // $keyword_in[$keyword]['title'] = round(( $count / $post_titles ) * 100, 2);
    230                     $post_title_words_array = explode(' ',$post_content['titles']);
     239                    $post_title_words_array = explode(' ', $post_content['titles']);
    231240                    $post_title_word_count = count($post_title_words_array);
    232                     $keyword_in[$keyword]['title'] = round(( $count / $post_title_word_count ) * 100, 2);
     241                    $keyword_in[$keyword]['title'] = round(($count / $post_title_word_count) * 100, 2);
    233242                    if ($keyword_in[$keyword]['added_count'] == 0) {
    234243                        $keyword_in[$keyword]['posts_count']++;
     
    236245                }
    237246            }
    238             $keyword_in['total_title_words_count']  = count(explode(' ',$post_content['titles']));
    239             $keyword_in['total_words']=$post_content['total'];
     247            $keyword_in['total_title_words_count'] = count(explode(' ', $post_content['titles']));
     248            $keyword_in['total_words'] = $post_content['total'];
    240249            $keys = array();
    241250            foreach ($keyword_in as $key => $value) {
     
    251260    }
    252261
    253     public function post_handling_by_portion($state,$getTopWords=false,$words=null){
     262    public function post_handling_by_portion($state, $getTopWords = false, $words = null)
     263    {
    254264        $publishedPostCount = wp_count_posts()->publish;
    255265        $expresscurate_posts_number = get_option('expresscurate_posts_number');
    256         $max_reported = ((!empty($expresscurate_posts_number))?get_option('expresscurate_posts_number'):100);
     266        $max_reported = ((!empty($expresscurate_posts_number)) ? get_option('expresscurate_posts_number') : 100);
    257267        $number_of_post = min($publishedPostCount, $max_reported);
    258         $iteration = min($publishedPostCount,200);
    259         for ($i = 0; $i < $number_of_post; $i+=$iteration) {
     268        $iteration = min($publishedPostCount, 200);
     269        for ($i = 0; $i < $number_of_post; $i += $iteration) {
    260270            $args = array('status' => 'published', 'numberposts' => min($i + $number_of_post, $max_reported), 'offset' => 0);
    261             if($state=="words"){
     271            if ($state == "words") {
    262272                $wordsPart = $this->get_words($args, false);
    263273                $portions[] = $wordsPart['words'];
    264             }
    265             else if($state=="stats"){
    266                 if($getTopWords){
     274            } else if ($state == "stats") {
     275                if ($getTopWords) {
    267276                    $keywords = $words;
    268277                } else {
     
    270279                }
    271280                $portions[] = $this->get_stats($keywords, $args, false, true);
    272             }
    273             else if($state=="posts"){  $posts = array_merge($posts, get_posts($args)); }
     281            } else if ($state == "posts") {
     282                $posts = get_posts($args);
     283                $posts = array_merge($posts, get_posts($args));
     284            }
    274285        }
    275286        return $portions;
    276287    }
    277288
    278     public function getKeywordStats($getTopWords = false){
     289    public function getKeywordStats($getTopWords = false)
     290    {
    279291        $stats = array();
    280292        $resultArray = array();
    281293
    282         if($getTopWords) {
     294        if ($getTopWords) {
    283295            $words = array();
    284296
     
    291303            if (!empty($words)) {
    292304                for ($i = 1; $i < count($words); $i++) {
    293                     foreach ($words[$i] as $word => $count){
    294                         if (!empty($words[0][$word])){
     305                    foreach ($words[$i] as $word => $count) {
     306                        if (!empty($words[0][$word])) {
    295307                            $words[0][$word] += $count;
    296308                        } else {
     
    301313            }
    302314            $definedKeyWords = get_option('expresscurate_defined_tags', true);
    303             if (!empty($words[0])){
     315            if (!empty($words[0])) {
    304316                $words = array_keys(array_slice($words[0], 0, 30, true));
    305317            }
    306             if (!empty($definedKeyWords) && !empty($words)){
     318            if (!empty($definedKeyWords) && !empty($words)) {
    307319                $definedKeywordsArray = explode(',', strtolower(str_replace(' ', '', $definedKeyWords)));
    308320
    309                 foreach ($definedKeywordsArray as $definedKeyword){
    310                     if(($key = array_search($definedKeyword, $words)) !== false) {
     321                foreach ($definedKeywordsArray as $definedKeyword) {
     322                    if (($key = array_search($definedKeyword, $words)) !== false) {
    311323                        unset($words[$key]);
    312324                    }
     
    314326            }
    315327
    316        }
    317 /*        for ($i = 0; $i <= ceil($publishedPostCount / 200); $i++) {
    318             $args = array('status' => 'published', 'numberposts' => 200, 'offset' => $i * 200);
    319 
    320         }*/
    321         $stats = $this->post_handling_by_portion('stats',$getTopWords,$words);
    322 
    323         if(count($stats) > 1) {
    324             for ($i = 1; $i < count($stats); $i++){
     328        }
     329        /*        for ($i = 0; $i <= ceil($publishedPostCount / 200); $i++) {
     330                    $args = array('status' => 'published', 'numberposts' => 200, 'offset' => $i * 200);
     331
     332                }*/
     333        $stats = $this->post_handling_by_portion('stats', $getTopWords, $words);
     334
     335        if (count($stats) > 1) {
     336            for ($i = 1; $i < count($stats); $i++) {
    325337                $stats[0]['total_words'] += $stats[$i]['total_words'];
    326338                $stats[0]['total_title_words_count'] += $stats[$i]['total_title_words_count'];
    327                 foreach($stats[$i] as $key => $value) {
    328                     if($key == 'count' || $key == 'title_matches' || $key == 'posts_count'){
     339                foreach ($stats[$i] as $key => $value) {
     340                    if ($key == 'count' || $key == 'title_matches' || $key == 'posts_count') {
    329341                        $stats[0][$key] += $value;
    330342                    }
     
    334346        }
    335347        if (!empty($stats[0])) {
    336             foreach($stats[0] as &$stat){
    337                 if(is_array($stat)){
    338                     if(0 !== $stats[0]['total_title_words_count']) {
     348            foreach ($stats[0] as &$stat) {
     349                if (is_array($stat)) {
     350                    if (0 !== $stats[0]['total_title_words_count']) {
    339351                        $stat['title'] = round(($stat['title_matches'] / ($stats[0]['total_title_words_count'])) * 100, 2);
    340                     }else{
    341                         $stat['title'] = 0 ;
    342                     }
    343                     if(0 !== $stats[0]['total_words']){
    344                         $stat['percent'] = round(($stat['count']/($stats[0]['total_words']))*100, 2);
    345                     }else{
     352                    } else {
     353                        $stat['title'] = 0;
     354                    }
     355                    if (0 !== $stats[0]['total_words']) {
     356                        $stat['percent'] = round(($stat['count'] / ($stats[0]['total_words'])) * 100, 2);
     357                    } else {
    346358                        $stat['percent'] = 0;
    347359                    }
    348360                    if ($stat['percent'] < 3) {
    349361                        $color = 'blue';
    350                     } elseif ($stat['percent'] >= 3 && $stat['percent']<= 5) {
     362                    } elseif ($stat['percent'] >= 3 && $stat['percent'] <= 5) {
    351363                        $color = 'green';
    352364                    } elseif ($stat['percent'] > 5) {
     
    359371            unset($stats[0]['total_title_words_count']);
    360372            $resultArray = $stats[0];
    361         }else{
     373        } else {
    362374            $defined_tags = get_option("expresscurate_defined_tags", '');
    363             if(!empty($defined_tags)){
     375            if (!empty($defined_tags)) {
    364376                $keywords_arr = $this->array_map('trim', explode(",", $defined_tags));
    365                 foreach($keywords_arr as $tag){
     377                foreach ($keywords_arr as $tag) {
    366378                    $resultArray[$tag] = array(
    367                         "added_count"=> 0,
    368                         "color"=> "blue",
    369                         "count"=> 0,
    370                         "percent"=> 0,
    371                         "posts_count"=> 0,
    372                         "title"=> 0,
    373                         "title_matches"=> 0
     379                        "added_count" => 0,
     380                        "color" => "blue",
     381                        "count" => 0,
     382                        "percent" => 0,
     383                        "posts_count" => 0,
     384                        "title" => 0,
     385                        "title_matches" => 0
    374386                    );
    375387                }
    376388            }
    377389        }
    378 
    379390        return $resultArray;
    380391    }
    381 
    382 
    383   public function array_map($func, $array) {
    384     $new_array = array();
    385     foreach ($array as $key => $value) {
    386       $new_array[$key] = call_user_func($func, $value);
    387     }
    388     return $new_array;
    389   }
    390 
    391   public function array_map_keys($func, $array,$utf8) {
    392     $new_array = array();
    393     foreach ($array as $key => $value) {
    394         $new_array[call_user_func($func, $key,$utf8)] = $value;
    395     }
    396     return $new_array;
    397   }
    398 
    399   public function suggestKeywordsFromGoogle(){
    400 
    401       $term   = urlencode( $_GET['term'] );
    402       $mixed   = urlencode( $_GET['mixed'] );
    403 
    404       $result = wp_remote_get( 'https://www.google.com/complete/search?output=toolbar&q=' . $term );
    405 
    406       $return_arr = array();
    407 
    408       if ( ! is_wp_error( $result ) ) {
    409           preg_match_all( '`suggestion data="([^"]+)"/>`u', $result['body'], $matches );
    410 
    411           if ( isset( $matches[1] ) && ( is_array( $matches[1] ) && $matches[1] !== array() ) ) {
    412               foreach ( $matches[1] as $match ) {
    413                   $return_arr[] = html_entity_decode( $match, ENT_COMPAT, 'UTF-8' );
    414               }
    415           }
    416       }
    417 
    418       $defined_tags_arr = array();
    419       if(!empty($mixed)){
    420           $defined_tags = get_option("expresscurate_defined_tags", '');
    421           if ($defined_tags) {
    422               $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
    423               foreach ($defined_tags_arr as $keyword) {
    424                   if (strpos($keyword, $term) === false){
    425                       if(($key = array_search($keyword, $defined_tags_arr)) !== false) {
    426                           unset($defined_tags_arr[$key]);
    427                       }
    428                   }
    429               }
    430               unset($defined_tags_arr['']);
    431           }
    432       }
    433       $return_arr = array_merge($defined_tags_arr, $return_arr);
    434       echo json_encode( $return_arr );
    435       die();
    436 
    437   }
     392    public function get_post_analytics_stats()
     393    {
     394        $stats=$this->getKeywordStats(false);
     395        echo json_encode($stats);die;
     396    }
     397
     398    public function array_map($func, $array)
     399    {
     400        $new_array = array();
     401        foreach ($array as $key => $value) {
     402            $new_array[$key] = call_user_func($func, $value);
     403        }
     404        return $new_array;
     405    }
     406
     407    public function array_map_keys($func, $array, $utf8)
     408    {
     409        $new_array = array();
     410        foreach ($array as $key => $value) {
     411            $new_array[call_user_func($func, $key, $utf8)] = $value;
     412        }
     413        return $new_array;
     414    }
     415
     416    public function suggestKeywordsFromGoogle()
     417    {
     418
     419        $term = urlencode($_GET['term']);
     420        $mixed = urlencode($_GET['mixed']);
     421
     422        $result = wp_remote_get('https://www.google.com/complete/search?output=toolbar&q=' . $term);
     423
     424        $return_arr = array();
     425
     426        if (!is_wp_error($result)) {
     427            preg_match_all('`suggestion data="([^"]+)"/>`u', $result['body'], $matches);
     428
     429            if (isset($matches[1]) && (is_array($matches[1]) && $matches[1] !== array())) {
     430                foreach ($matches[1] as $match) {
     431                    $return_arr[] = html_entity_decode($match, ENT_COMPAT, 'UTF-8');
     432                }
     433            }
     434        }
     435
     436        $defined_tags_arr = array();
     437        if (!empty($mixed)) {
     438            $defined_tags = get_option("expresscurate_defined_tags", '');
     439            if ($defined_tags) {
     440                $defined_tags_arr = $this->array_map('trim', explode(",", $defined_tags));
     441                foreach ($defined_tags_arr as $keyword) {
     442                    if (strpos($keyword, $term) === false) {
     443                        if (($key = array_search($keyword, $defined_tags_arr)) !== false) {
     444                            unset($defined_tags_arr[$key]);
     445                        }
     446                    }
     447                }
     448                unset($defined_tags_arr['']);
     449            }
     450        }
     451        $return_arr = array_merge($defined_tags_arr, $return_arr);
     452        echo json_encode($return_arr);
     453        die();
     454
     455    }
    438456
    439457}
  • expresscurate/trunk/ExpressCurate_Tracker.php

    r1109426 r1129694  
    5656
    5757        <script type="text/javascript">
    58             var expresscurate_track_hash = '<?php echo $hash; ?>',
     58            var expresscurate_track_hash = '<?php echo $this->hash; ?>',
    5959                siteSendAnalytics = false,
    6060                siteWpSendAnalytics = false;
     
    122122            });
    123123            <?php } }
    124             if((get_option('expresscurate_post_status') && get_option('expresscurate_post_status')=="publish") && ($pagenow=="post-new.php" || $pagenow=="post.php")){
     124            if((get_option('expresscurate_changed_post_status') && get_option('expresscurate_changed_post_status')=="publish") && ($pagenow=="post-new.php" || $pagenow=="post.php")){
    125125                ?>
    126126            ga('expresscurate.send', 'pageview', {
    127                 'page': '/post-edit/publish'
     127                'page': '/action/wp/post-edit/publish'
    128128            });
    129129            <?php
    130                update_option('expresscurate_post_status','');
     130               update_option('expresscurate_changed_post_status','');
    131131            }
    132132            ?>
  • expresscurate/trunk/css/expresscurate.css

    r1115335 r1129694  
    165165    font-family:  OpenSans-Regular, Verdana, Geneva, sans-serif;
    166166    cursor: default;
     167    display: block;
    167168}
    168169.expresscurate_emptyFeed{
     
    611612    background-color: #f5f6f6;
    612613}
    613     .expresscurate_bookmarks .addBookmark span,
    614     .expresscurate_feed_dashboard .addFeed span,
    615     .expresscurate_keywords_settings .addKeywords span{
     614    .expresscurate_bookmarks .addBookmark span.plus,
     615    .expresscurate_feed_dashboard .addFeed span.plus,
     616    .expresscurate_keywords_settings .addKeywords span.plus{
    616617        height: 34px;
    617618        width: 35px;
     
    629630        font-weight: bold;
    630631    }
    631 .expresscurate_bookmarks .addBookmark > span:hover,
    632 .expresscurate_feed_dashboard .addFeed > span:hover,
    633 .expresscurate_keywords_settings .addKeywords > span:hover{
     632.expresscurate_bookmarks .addBookmark > span.plus:hover,
     633.expresscurate_feed_dashboard .addFeed > span.plus:hover,
     634.expresscurate_keywords_settings .addKeywords > span.plus:hover{
    634635    background-color: #20d0b1;
    635636}
     
    640641            background: url("../images/plus.svg") no-repeat transparent center;
    641642            background-size: 14px;
     643            display: block;
     644            width: 100%;
     645            height: 100%;
    642646        }
    643647    .expresscurate_keywords_settings .suggestion,
     
    14551459}
    14561460
     1461#expresscurate_socialModal,
    14571462#expresscurate_open-modal {
    14581463    padding: 0 10px 0 0;
    14591464}
    14601465
    1461 .expresscurate_button_icon {
     1466.expresscurate_button_icon{
    14621467    background: url("../images/wp_quotes.svg") no-repeat center -105px rgba(0, 0, 0, 0);
    14631468    background-size: 12px auto;
     1469}
     1470.expresscurate_socialModal{
     1471    background: url("../images/wp_icons.svg") no-repeat center -324px rgba(0, 0, 0, 0);
     1472    background-size: 18px auto;
     1473}
     1474.expresscurate_button_icon,
     1475.expresscurate_socialModal{
    14641476    display: block;
    14651477    float: left;
     
    14691481    width: 16px;
    14701482}
    1471 
     1483.expresscurate_socialDialog{
     1484    padding: 10px 30px !important;
     1485    font-family: OpenSans-Regular, Verdana, Geneva, sans-serif;
     1486    height: 100% !important;
     1487}
     1488
     1489.expresscurate_socialDialog ul{
     1490    width: 100%;
     1491    padding: 0;
     1492    margin-top: 10px;
     1493}
     1494.expresscurate_socialDialog ul li{
     1495    width: 35px;
     1496    height: 35px;
     1497    box-sizing: border-box;
     1498    -moz-box-sizing: border-box;
     1499    -webkit-box-sizing: border-box;
     1500    text-align: right;
     1501    background-color: #f3f3f3;
     1502    display:inline-block;
     1503    margin: 5px 0;
     1504    background: url("../images/socials_embed.svg") no-repeat;
     1505    background-size: auto 100px;
     1506}
     1507
     1508.expresscurate_socialDialog ul li.facebook{
     1509    background-position: 0 1px;
     1510}
     1511/*.expresscurate_socialDialog ul li.facebook:hover,*/
     1512.expresscurate_socialDialog ul li.facebook.current{
     1513    background-position: 0 -66px;
     1514}
     1515.expresscurate_socialDialog ul li.twitter{
     1516    background-position: -65px 1px;
     1517}
     1518/*.expresscurate_socialDialog ul li.twitter:hover,*/
     1519.expresscurate_socialDialog ul li.twitter.current{
     1520    background-position: -65px -66px;
     1521}
     1522.expresscurate_socialDialog ul li.youtube{
     1523    background-position: -132px 1px;
     1524}
     1525/*.expresscurate_socialDialog ul li.youtube:hover,*/
     1526.expresscurate_socialDialog ul li.youtube.current{
     1527    background-position: -132px -66px;
     1528}
     1529.expresscurate_socialDialog ul li.vimeo{
     1530    background-position: -200px 1px;
     1531}
     1532/*.expresscurate_socialDialog ul li.vimeo:hover,*/
     1533.expresscurate_socialDialog ul li.vimeo.current{
     1534    background-position: -200px -66px;
     1535}
     1536.expresscurate_socialDialog .tab-content{
     1537    width: 100%;
     1538    padding: 0;
     1539    margin-top: 10px;
     1540    box-sizing: border-box;
     1541    -moz-box-sizing: border-box;
     1542    -webkit-box-sizing: border-box;
     1543    position: relative;
     1544    overflow: hidden;
     1545}
     1546.expresscurate_socialDialog .tab-content textarea{
     1547    height: 80px;
     1548    width: 100%;
     1549    white-space: normal;
     1550    overflow-x: hidden;
     1551    resize: none;
     1552    background-color: #f6f6f6;
     1553    border-radius: 2px;
     1554    -webkit-border-radius: 2px;
     1555    -moz-border-radius: 2px;
     1556    box-shadow: none;
     1557    -moz-box-shadow: none;
     1558    -webkit-box-shadow: none;
     1559    font-size: 13px;
     1560    border: solid 1px #d6d6d6;
     1561    padding: 5px 10px;
     1562    box-sizing: border-box;
     1563    -moz-box-sizing: border-box;
     1564    -webkit-box-sizing: border-box;
     1565}
     1566 .mce-expresscurate_socialInsertButton{
     1567     left: auto !important;
     1568     right: 40px !important;
     1569 }
     1570 .mce-expresscurate_socialInsertButton button{
     1571    display: inline-block;
     1572    background-color: #1cbb9f;
     1573    color: #ffffff;
     1574    padding: 0 10px;
     1575    line-height: 28px;
     1576    height: 28px;
     1577    border: transparent;
     1578    text-decoration: none;
     1579}
     1580 .mce-expresscurate_socialInsertButton:hover button{
     1581    background-color: #20d0b1;
     1582}
     1583.mce-expresscurate_socialInsertButton button{
     1584    transition: all .3s ease-out;
     1585    -moz-transition: all .3s ease-out;
     1586    -webkit-transition: all .3s ease-out;
     1587    border-radius: 3px;
     1588    -moz-border-radius: 3px;
     1589    -webkit-border-radius: 3px;
     1590    box-sizing: border-box;
     1591    -moz-box-sizing: border-box;
     1592    -webkit-box-sizing: border-box;
     1593}
    14721594.expresscurate_text {
    14731595    margin-left: 5px;
     
    25122634    width: auto;
    25132635}
    2514 .expresscurate_advancedSEO_widget .lengthSuggestion,
    2515 #expresscurate_wordCount_dialog .lengthSuggestion{
     2636.expresscurate_advancedSEO_widget .lengthSuggestion{
    25162637    position: relative;
    25172638    margin: 20px ;
     
    25202641    white-space: normal;
    25212642}
    2522 #expresscurate_wordCount_dialog{
    2523     height: auto !important;
    2524     max-width: 700px !important;
    2525     white-space: normal;
    2526 }
    2527 .expresscurate_advancedSEO_widget .lengthSuggestion:before,
    2528 #expresscurate_wordCount_dialog .lengthSuggestion:before{
     2643.expresscurate_advancedSEO_widget .lengthSuggestion:before{
    25292644    display: inline-block;
    25302645    width: 15px;
     
    25352650    top: 2px;
    25362651}
    2537 .expresscurate_advancedSEO_widget .lengthSuggestion.blue:before,
    2538 #expresscurate_wordCount_dialog .lengthSuggestion.blue:before{
     2652.expresscurate_advancedSEO_widget .lengthSuggestion.blue:before{
    25392653    background-color: #3598dc;
    25402654}
    2541 .expresscurate_advancedSEO_widget .lengthSuggestion.green:before,
    2542 #expresscurate_wordCount_dialog .lengthSuggestion.green:before{
     2655.expresscurate_advancedSEO_widget .lengthSuggestion.green:before{
    25432656    background-color: #3dc577;
    25442657}
    2545 .expresscurate_advancedSEO_widget .lengthSuggestion.red:before,
    2546 #expresscurate_wordCount_dialog .lengthSuggestion.red:before{
     2658.expresscurate_advancedSEO_widget .lengthSuggestion.red:before{
    25472659    background-color: #e84c3d;
    2548 }
    2549 #expresscurate_wordCount_dialog .mce-foot{
    2550     display: none !important;
    25512660}
    25522661/*mark keyword dialog*/
    25532662#expresscurate_keyword_dialog{
    2554     height: 100px !important;
     2663    height: 80px !important;
    25552664}
    25562665#expresscurate_keyword_dialog-body{
    2557     height: 80px !important;
     2666    height: 50px !important;
    25582667    background-color: #fff;
    25592668    padding: 10px 15px!important;
    25602669    box-sizing: border-box;
    25612670}
     2671#ExpresscurateEmbed .mce-foot,
    25622672#expresscurate_keyword_dialog .mce-foot,
    25632673#expresscurate_keyword_dialog .mce-first{
    2564     display: none;
     2674    border-radius: 0 !important;
     2675    -moz-border-radius: 0 !important;
    25652676}
    25662677.expresscurate_keywordMessage{
    25672678    display: block;
    2568 }
    2569 #expresscurate_keyword_dialog a.button-primary{
    2570     display: inline-block;
    2571     float: right;
    2572     margin-top: 15px;
    2573 }
    2574 #expresscurate_keyword_dialog a.cancel{
    2575     display: inline-block;
    2576     margin-top: 20px;
    2577     color: #a00;
    2578 }
    2579 #expresscurate_keyword_dialog a.cancel:hover{
    2580     color: red;
    25812679}
    25822680/*Settings page*/
     
    27622860    border-radius: 3px;
    27632861    text-decoration: none;
    2764 
    27652862    transition: all .3s ease-out;
    27662863    -moz-transition: all .3s ease-out;
     
    28482945.expresscurate_post_type[type=radio]:checked + label:after {
    28492946    background: url("../images/feed_icons.svg") no-repeat -79px -24px;
    2850     background-size: 96px auto;
     2947    background-size: auto 68px;
    28512948    visibility: visible;
    28522949    opacity: 1;
     
    30033100            padding: 17px 35px;
    30043101        }
    3005         .expresscurate_feed_dashboard .addNewFeed .errorMessage,
    3006         .expresscurate_bookmarks .addNewBookmark .errorMessage,
    3007         .expresscurate_errorMessage{
    3008             color: #e84c3d !important;
    3009             font-size: 13px !important;
    3010             line-height: 16px;
    3011             width: auto !important;
    3012         }
    3013         #expresscurate_widget .expresscurate_errorMessage{
    3014             margin-left: 7px;
    3015         }
     3102/*validation error message*/
     3103.expresscurate_errorMessage.errorActive {
     3104    left: 0;
     3105    opacity: 1;
     3106}
     3107.expresscurate_errorMessage {
     3108    font-size: 12px !important;
     3109    line-height: 13px !important;
     3110    font-family: OpenSans-Light, Verdana, Geneva, sans-serif !important;
     3111    position: absolute !important;
     3112    top: 6px;
     3113    left: -100%;
     3114    opacity: 0;
     3115    z-index: 100;
     3116    background: #e85e50 !important;
     3117    width: auto;
     3118    height: auto;
     3119    border-top-right-radius: 3px;
     3120    border-bottom-right-radius: 3px;
     3121    border-top-left-radius: 0 !important;
     3122    border-bottom-left-radius: 0 !important;
     3123    color: #fff !important;
     3124    -webkit-transition: all 0.3s ease-out;
     3125    -moz-transition: all 0.3s ease-out;
     3126    -ms-transition: all 0.3s ease-out;
     3127    -o-transition: all 0.3s ease-out;
     3128    transition: all 0.3s ease-out;
     3129    text-align: left;
     3130    max-width: 100%;
     3131    padding: 5px 10px !important;
     3132    margin: 0 !important;
     3133}
     3134.expresscurate_supportBlock .expresscurate_errorMessage,
     3135.expresscurate_support .expresscurate_errorMessage,
     3136.expresscurate_faq .expresscurate_errorMessage{
     3137    top: 23px;
     3138}
     3139.expresscurate_errorMessageInput{
     3140    background-color: #D9D9D9 !important;
     3141}
    30163142        .expresscurate_support > div > label,
    30173143        .expresscurate_faq > div > label{
     
    30963222                padding:0 20px;
    30973223            }
    3098                 .expresscurate_supportBlock textarea{
    3099                     margin-top: 20px !important;
    3100                 }
    31013224                .expresscurate_supportBlock input,
    31023225            .expresscurate_support .block input,
     
    31043227                height: 40px;
    31053228                line-height: 40px;
    3106                 margin-top: 15px;
     3229                margin: 15px 0 0 0;
    31073230            }
    31083231            .expresscurate_supportBlock textarea,
     
    31123235                overflow: hidden;
    31133236                height: 150px;
    3114                 margin: 5px 0 0 0;
     3237                margin: 15px 0 0 0;
    31153238            }
    31163239            .expresscurate_supportBlock .send,
     
    31983321    .expresscurate_faq,.expresscurate_support{
    31993322        margin: 0 20px 0 0 !important;
    3200         width: 98%;
     3323        width: 96%;
    32013324    }
    32023325    .expresscurate_support .block label,
     
    34703593            margin-top: 10px;
    34713594            position: relative;
     3595            overflow: hidden;
    34723596        }
    34733597        .expresscurate_feed_dashboard .addFeed{
     
    34763600            margin-top: 10px;
    34773601            position: relative;
     3602            overflow: hidden;
    34783603        }
    34793604        .expresscurate_bookmarks .addBookmark input{
     
    35303655            background-image: url("../images/feed_icons.svg");
    35313656            background-repeat: no-repeat;
    3532             background-size: 115px auto;
     3657            background-size: auto 82px;
    35333658            cursor: default;
    35343659            position: relative;
     
    35603685                background-image: url("../images/feed_icons.svg");
    35613686                background-color: transparent;
    3562                 background-size: 140px auto;
     3687                background-size: auto 100px;
    35633688                background-position: -104px -35px;
    35643689                cursor: pointer;
     
    35943719                background-position: -50px 8px;
    35953720            }
    3596 
     3721            .expresscurate_feed_list .feedListControls .pull{
     3722                background-position: -144px 6px;
     3723                background-size: auto 99px;
     3724                margin-right: 10px;
     3725            }
     3726            .expresscurate_feed_list .feedListControls .pullTime{
     3727                background-image: none;
     3728                width: 110px;
     3729                height: 32px;
     3730                border-right: none;
     3731                color: #565656;
     3732                font-family: OpenSans-Semibold, Verdana, Geneva, sans-serif;
     3733                font-size: 12px;
     3734                line-height: 12px;
     3735                padding: 3px 0 5px 10px;
     3736                box-sizing: border-box;
     3737                -moz-box-sizing: border-box;
     3738                -webkit-box-sizing: border-box;
     3739                cursor: default;
     3740            }
     3741                .expresscurate_feed_list .feedListControls .pullTime p{
     3742                    color: #414141;
     3743                    font-family: OpenSans-Light , Verdana, Geneva, sans-serif;
     3744                    margin: 0;
     3745                    line-height: 12px;
     3746                    font-size: 12px;
     3747                }
     3748            .expresscurate_feed_list .feedListControls .pullTime:hover{
     3749                background: transparent;
     3750                cursor: default;
     3751            }
    35973752            .expresscurate_controls .quotes.active:hover{
    35983753                background-position: 19px -59px;
     
    36103765                border-color: #1cbb9f;
    36113766            }
     3767            .expresscurate_feed_list .feedListControls .pull.active:hover{
     3768                background-position: -144px -74px;
     3769                background-color: #1cbb9f;
     3770                border-color: #1cbb9f;
     3771            }
    36123772
    36133773            .expresscurate_controls .quotes.active{
     
    36193779            .expresscurate_controls .remove.active{
    36203780                background-position: -50px -25px;
     3781            }
     3782            .expresscurate_feed_list .feedListControls .pull.active{
     3783                background-position: -144px -33px;
    36213784            }
    36223785
     
    38293992        .expresscurate_feedBoxes .checkInput[type=checkbox]:checked + label{
    38303993            background: url("../images/feed_icons.svg") no-repeat -86px 1px;
    3831             background-size: 100px auto;
     3994            background-size: auto 72px;
    38323995        }
    38333996        .expresscurate_bookmarkBoxes li input[type=checkbox],
     
    39534116                padding: 0;
    39544117            }
     4118            .expresscurate_bookmarkBoxes .keywords  .videos:hover,
     4119            .expresscurate_feedBoxes .keywords  .videos:hover,
     4120            .expresscurate_bookmarkBoxes .keywords  .images:hover,
     4121            .expresscurate_feedBoxes .keywords  .images:hover{
     4122                background-color: #4cc3ab;
     4123            }
    39554124            .expresscurate_bookmarkBoxes .keywords  .videos,
    39564125            .expresscurate_feedBoxes .keywords  .videos{
     
    39954164                height: 28px;
    39964165                line-height: 28px;
    3997                 width: 85px;
     4166                width: 100px;
    39984167                bottom: auto;
    39994168                top: 30px;
    4000                 left:-22px;
     4169                left:-37px;
    40014170                text-align: center;
    40024171            }
     
    40044173            .expresscurate_feedBoxes .keywords .media .tooltip:before{
    40054174                border-bottom-color: #000;
    4006                 left: 30px;
     4175                left: 45px;
    40074176            }
    40084177        .expresscurate_bookmarkBoxes .controls,
     
    46044773    min-height: 280px;
    46054774}
     4775.expresscurate_support form > .errorMessageWrap,
     4776#expresscurate_support_form .errorMessageWrap{
     4777    position: relative;
     4778    min-height: inherit;
     4779    padding: 0;
     4780    border: none;
     4781    margin: 0;
     4782    max-width: inherit;
     4783    overflow: hidden;
     4784}
    46064785.expresscurate_blocks.wrap{
    46074786    margin: 0 !important;
  • expresscurate/trunk/css/quotes-style.css

    r1109426 r1129694  
    3535blockquote:after ,
    3636blockquote:before{
    37     background-size: 97px auto;
     37    background-size: auto 68px;
    3838    background-repeat: no-repeat;
    3939    background-image: url('../images/feed_icons.svg');
     
    4343    bottom: -13px;
    4444    width: 12px;
    45     height: 27px;
     45    height: 23px;
    4646    text-align: right;
    4747    position: absolute;
  • expresscurate/trunk/images/feed_icons.svg

    r1053405 r1129694  
    33<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    44<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
    5      width="616.188px" height="440.846px" viewBox="0 0 616.188 440.846" enable-background="new 0 0 616.188 440.846"
     5     width="782.447px" height="440.846px" viewBox="0 0 782.447 440.846" enable-background="new 0 0 782.447 440.846"
    66     xml:space="preserve">
    77<g>
    88    <g>
    9         <path fill="#B5B6B6" d="M42.204,5.059h32.79v31.68c0,0,1.258,30.607-32.54,39.045V62.112c0,0,16.9-4.048,19.321-24.364H42.204
    10             V5.059z"/>
    11         <path fill="#B5B6B6" d="M0,5.059h32.79v31.68c0,0,1.262,30.607-32.538,39.045V62.112c0,0,16.899-4.048,19.321-24.364H0V5.059z"/>
     9        <g>
     10            <path fill="#B5B6B6" d="M42.204,5.059h32.79v31.68c0,0,1.258,30.607-32.54,39.045V62.112c0,0,16.9-4.048,19.321-24.364H42.204
     11                V5.059z"/>
     12            <path fill="#B5B6B6" d="M0,5.059h32.79v31.68c0,0,1.262,30.607-32.538,39.045V62.112c0,0,16.899-4.048,19.321-24.364H0V5.059z"/>
     13        </g>
     14        <polygon id="star-2-icon_5_" fill="#B5B6B6" points="217.502,0 230.496,26.804 260.002,30.879 238.527,51.518 243.768,80.841
     15            217.502,66.793 191.235,80.841 196.479,51.518 175.002,30.879 204.508,26.804      "/>
     16        <polygon id="plus-2-icon_5_" fill="#B5B6B6" points="435.001,64.118 411.307,40.422 435.001,16.724 421.197,2.921 397.502,26.618
     17            373.805,2.921 360.004,16.724 383.698,40.422 360.004,64.118 373.805,77.921 397.502,54.225 421.197,77.921         "/>
     18        <polygon id="check-mark-icon_2_" fill="#B5B6B6" points="604.207,9.81 566.936,47.083 550.79,30.935 538.817,42.91
     19            566.936,71.035 616.188,21.78        "/>
     20        <g>
     21            <path fill="#23B99E" d="M42.205,185.062h32.79v31.68c0,0,1.258,30.606-32.54,39.045v-13.671c0,0,16.9-4.049,19.321-24.364H42.205
     22                V185.062z"/>
     23            <path fill="#23B99E" d="M0.001,185.062h32.79v31.68c0,0,1.262,30.606-32.538,39.045v-13.671c0,0,16.899-4.049,19.321-24.364
     24                H0.001V185.062z"/>
     25        </g>
     26        <polygon id="star-2-icon_2_" fill="#23B99E" points="217.503,180.003 230.497,206.807 260.003,210.882 238.528,231.521
     27            243.769,260.844 217.503,246.796 191.236,260.844 196.479,231.521 175.003,210.882 204.509,206.807         "/>
     28        <polygon id="plus-2-icon_2_" fill="#23B99E" points="435.002,244.121 411.308,220.425 435.002,196.727 421.198,182.924
     29            397.503,206.621 373.806,182.924 360.005,196.727 383.699,220.425 360.005,244.121 373.806,257.924 397.503,234.228
     30            421.198,257.924         "/>
     31        <polygon id="check-mark-icon_3_" fill="#23B99E" points="604.208,189.813 566.936,227.085 550.791,210.938 538.818,222.913
     32            566.936,251.038 616.188,201.783         "/>
     33        <g>
     34            <path fill="#FFFFFF" d="M42.205,365.063h32.79v31.68c0,0,1.258,30.606-32.54,39.045v-13.671c0,0,16.9-4.049,19.321-24.364H42.205
     35                V365.063z"/>
     36            <path fill="#FFFFFF" d="M0.001,365.063h32.79v31.68c0,0,1.262,30.606-32.538,39.045v-13.671c0,0,16.899-4.049,19.321-24.364
     37                H0.001V365.063z"/>
     38        </g>
     39        <polygon id="star-2-icon_7_" fill="#FFFFFF" points="217.503,360.004 230.497,386.81 260.003,390.883 238.528,411.521
     40            243.769,440.846 217.503,426.797 191.236,440.846 196.479,411.521 175.003,390.883 204.509,386.81      "/>
     41        <polygon id="plus-2-icon_7_" fill="#FFFFFF" points="435.002,424.124 411.308,400.426 435.002,376.729 421.198,362.926
     42            397.503,386.623 373.806,362.926 360.005,376.729 383.699,400.426 360.005,424.124 373.806,437.926 397.503,414.23
     43            421.198,437.926         "/>
     44        <polygon id="check-mark-icon_5_" fill="#FFFFFF" points="604.208,369.815 566.936,407.087 550.791,390.94 538.818,402.915
     45            566.936,431.04 616.188,381.785      "/>
    1246    </g>
    13     <polygon id="star-2-icon_5_" fill="#B5B6B6" points="217.502,0 230.496,26.804 260.002,30.879 238.527,51.518 243.768,80.841
    14         217.502,66.793 191.235,80.841 196.479,51.518 175.002,30.879 204.508,26.804  "/>
    15     <polygon id="plus-2-icon_5_" fill="#B5B6B6" points="435.001,64.118 411.307,40.422 435.001,16.724 421.197,2.921 397.502,26.618
    16         373.805,2.921 360.004,16.724 383.698,40.422 360.004,64.118 373.805,77.921 397.502,54.225 421.197,77.921     "/>
    17     <polygon id="check-mark-icon_2_" fill="#B5B6B6" points="604.207,9.81 566.935,47.083 550.79,30.935 538.817,42.91 566.935,71.035
    18         616.187,21.78   "/>
    19     <g>
    20         <path fill="#23B99E" d="M42.205,185.062h32.79v31.68c0,0,1.258,30.607-32.54,39.045v-13.671c0,0,16.9-4.048,19.321-24.364H42.205
    21             V185.062z"/>
    22         <path fill="#23B99E" d="M0.001,185.062h32.79v31.68c0,0,1.262,30.607-32.538,39.045v-13.671c0,0,16.899-4.048,19.321-24.364H0.001
    23             V185.062z"/>
    24     </g>
    25     <polygon id="star-2-icon_2_" fill="#23B99E" points="217.503,180.003 230.497,206.807 260.003,210.882 238.528,231.521
    26         243.769,260.844 217.503,246.796 191.236,260.844 196.479,231.521 175.003,210.882 204.509,206.807     "/>
    27     <polygon id="plus-2-icon_2_" fill="#23B99E" points="435.002,244.121 411.308,220.425 435.002,196.727 421.198,182.924
    28         397.503,206.621 373.806,182.924 360.005,196.727 383.699,220.425 360.005,244.121 373.806,257.924 397.503,234.228
    29         421.198,257.924     "/>
    30     <polygon id="check-mark-icon_3_" fill="#23B99E" points="604.208,189.813 566.936,227.085 550.791,210.938 538.818,222.913
    31         566.936,251.038 616.188,201.783     "/>
    32     <g>
    33         <path fill="#FFFFFF" d="M42.205,365.063h32.79v31.68c0,0,1.258,30.607-32.54,39.045v-13.671c0,0,16.9-4.048,19.321-24.364H42.205
    34             V365.063z"/>
    35         <path fill="#FFFFFF" d="M0.001,365.063h32.79v31.68c0,0,1.262,30.607-32.538,39.045v-13.671c0,0,16.899-4.048,19.321-24.364H0.001
    36             V365.063z"/>
    37     </g>
    38     <polygon id="star-2-icon_7_" fill="#FFFFFF" points="217.503,360.004 230.497,386.809 260.003,390.883 238.528,411.522
    39         243.769,440.846 217.503,426.797 191.236,440.846 196.479,411.522 175.003,390.883 204.509,386.809     "/>
    40     <polygon id="plus-2-icon_7_" fill="#FFFFFF" points="435.002,424.124 411.308,400.426 435.002,376.729 421.198,362.926
    41         397.503,386.623 373.806,362.926 360.005,376.729 383.699,400.426 360.005,424.124 373.806,437.926 397.503,414.23
    42         421.198,437.926     "/>
    43     <polygon id="check-mark-icon_5_" fill="#FFFFFF" points="604.208,369.815 566.936,407.087 550.791,390.94 538.818,402.915
    44         566.936,431.04 616.188,381.785  "/>
     47    <path fill="#B4B4B5" d="M771.418,27.365c0-9.069,1.785-14.295,9.413-16.757c-5.917-2.493-36.867-8.496-36.867,19.76
     48        c0,9.49,0,17.368,0,17.368h-11.027l24.755,24.797l24.756-24.797h-11.029C771.418,47.736,771.418,35.292,771.418,27.365z"/>
     49    <path fill="#20B89D" d="M771.418,207.368c0-9.069,1.785-14.295,9.413-16.757c-5.917-2.493-36.867-8.496-36.867,19.76
     50        c0,9.49,0,17.368,0,17.368h-11.027l24.755,24.798l24.756-24.798h-11.029C771.418,227.739,771.418,215.295,771.418,207.368z"/>
     51    <path fill="#FFFFFF" d="M771.418,387.37c0-9.069,1.785-14.295,9.413-16.757c-5.917-2.493-36.867-8.496-36.867,19.76
     52        c0,9.49,0,17.368,0,17.368h-11.027l24.755,24.798l24.756-24.798h-11.029C771.418,407.741,771.418,395.297,771.418,387.37z"/>
    4553</g>
    4654</svg>
  • expresscurate/trunk/images/wp_icons.svg

    r1053405 r1129694  
    33<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    44<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
    5      width="60.073px" height="1018.711px" viewBox="0 0 60.073 1018.711" enable-background="new 0 0 60.073 1018.711"
     5     width="60.073px" height="1124.203px" viewBox="0 0 60.073 1124.203" enable-background="new 0 0 60.073 1124.203"
    66     xml:space="preserve">
    77<g>
    88    <g>
    9         <rect x="36.076" y="20.639" fill="#2AA886" width="6.205" height="18.295"/>
    10         <rect x="27.312" y="26.078" fill="#2AA886" width="6.204" height="12.856"/>
    11         <rect x="18.547" y="31.517" fill="#2AA886" width="6.205" height="7.417"/>
     9        <rect x="36.076" y="20.639" fill="#2BA886" width="6.205" height="18.295"/>
     10        <rect x="27.312" y="26.078" fill="#2BA886" width="6.204" height="12.856"/>
     11        <rect x="18.547" y="31.517" fill="#2BA886" width="6.205" height="7.417"/>
    1212    </g>
    13     <path fill="#2AA886" d="M0,488.746v51h60v-51H0z M20,498.746h20v7H20V498.746z M40,529.746H20v-7h20V529.746z M50,517.746H10v-7h40
     13    <path fill="#2BA886" d="M0,488.746v51h60v-51H0z M20,498.746h20v7H20V498.746z M40,529.746H20v-7h20V529.746z M50,517.746H10v-7h40
    1414        V517.746z"/>
    15     <path fill="#2AA886" d="M0,368.746v51h60v-51H0z M10,378.746h27v7H10V378.746z M37,409.746H10v-7h27V409.746z M47,397.746H10v-7h37
     15    <path fill="#2BA886" d="M0,368.746v51h60v-51H0z M10,378.746h27v7H10V378.746z M37,409.746H10v-7h27V409.746z M47,397.746H10v-7h37
    1616        V397.746z"/>
    17     <path fill="#2AA886" d="M0,247.746v51h60v-51H0z M10,263.746h26v7H10V263.746z M46,282.746H10v-7h36V282.746z"/>
    18     <polygon fill="#2AA886" points="28.18,249.746 39.176,239.746 50.173,249.746     "/>
    19     <path fill="#2AA886" d="M0,608.746v51h60v-51H0z M50,649.746H23v-7h27V649.746z M50,637.746H13v-7h37V637.746z M50,625.746H23v-7
     17    <path fill="#2BA886" d="M0,247.746v51h60v-51H0z M10,263.746h26v7H10V263.746z M46,282.746H10v-7h36V282.746z"/>
     18    <polygon fill="#2BA886" points="28.18,249.746 39.176,239.746 50.173,249.746     "/>
     19    <path fill="#2BA886" d="M0,608.746v51h60v-51H0z M50,649.746H23v-7h27V649.746z M50,637.746H13v-7h37V637.746z M50,625.746H23v-7
    2020        h27V625.746z"/>
    2121    <g>
    22         <path id="link-icon_1_" fill="#2AA886" d="M42.242,875.447c-0.98,0.989-2.07,1.81-3.229,2.456
    23             c-6.465,3.592-14.78,1.727-18.968-4.57l5.021-5.059c1.457,3.289,5.05,5.149,8.618,4.34c1.344-0.307,2.619-0.983,3.658-2.031
     22        <path id="link-icon_4_" fill="#2BA886" d="M42.242,875.447c-0.98,0.989-2.07,1.81-3.229,2.456
     23            c-6.465,3.592-14.779,1.727-18.969-4.57l5.021-5.059c1.457,3.289,5.049,5.149,8.617,4.34c1.344-0.307,2.619-0.983,3.658-2.031
    2424            l9.621-9.695c2.92-2.941,2.904-7.713-0.041-10.635c-2.941-2.92-7.713-2.902-10.635,0.041l-2.967,2.988
    25             c-2.71-1.063-5.618-1.48-8.483-1.256l6.547-6.597c5.611-5.655,14.748-5.688,20.402-0.075c5.658,5.61,5.693,14.744,0.08,20.401
    26             L42.242,875.447z M26.966,890.849l6.547-6.598c-2.868,0.225-5.776-0.195-8.487-1.259l-2.966,2.989
    27             c-2.922,2.943-7.689,2.963-10.637,0.04c-2.94-2.919-2.962-7.69-0.038-10.636l9.621-9.694c2.931-2.954,7.708-2.946,10.635-0.04
     25            c-2.711-1.063-5.617-1.48-8.482-1.256l6.547-6.597c5.611-5.655,14.748-5.688,20.402-0.075c5.658,5.61,5.693,14.744,0.08,20.401
     26            L42.242,875.447z M26.967,890.849l6.547-6.598c-2.867,0.225-5.775-0.195-8.486-1.259l-2.967,2.989
     27            c-2.922,2.943-7.689,2.963-10.637,0.04c-2.939-2.919-2.961-7.69-0.037-10.636l9.621-9.694c2.93-2.954,7.707-2.946,10.635-0.04
    2828            c0.682,0.677,1.271,1.52,1.639,2.351l5.021-5.058c-0.533-0.802-1.084-1.49-1.797-2.195c-1.83-1.818-4.154-3.167-6.824-3.797
    29             c-3.465-0.82-7.169-0.344-10.345,1.424c-1.161,0.646-2.249,1.461-3.232,2.451l-9.621,9.695c-5.614,5.652-5.578,14.791,0.076,20.4
    30             C12.217,896.539,21.355,896.503,26.966,890.849z"/>
    31         <path id="arrow-16-icon_1_" fill="#28A885" d="M48.348,884.938v-3.728l8.764,8.75l-8.764,8.751v-3.729H29.174l10.031-10.045
     29            c-3.465-0.82-7.168-0.344-10.344,1.424c-1.162,0.646-2.25,1.461-3.232,2.451l-9.621,9.695c-5.615,5.652-5.578,14.791,0.076,20.4
     30            C12.217,896.539,21.355,896.503,26.967,890.849z"/>
     31        <path id="arrow-16-icon_4_" fill="#28A885" d="M48.348,884.938v-3.728l8.764,8.75l-8.764,8.751v-3.729H29.174l10.031-10.045
    3232            H48.348z"/>
    3333    </g>
    3434    <g>
    35         <path id="link-icon_2_" fill="#C2C2C2" d="M42.242,995.447c-0.98,0.989-2.07,1.81-3.229,2.456
    36             c-6.465,3.592-14.78,1.727-18.968-4.57l5.021-5.059c1.457,3.289,5.05,5.149,8.618,4.34c1.344-0.307,2.619-0.983,3.658-2.031
     35        <path id="link-icon_3_" fill="#C2C2C2" d="M42.242,995.447c-0.98,0.989-2.07,1.81-3.229,2.456
     36            c-6.465,3.592-14.779,1.727-18.969-4.57l5.021-5.059c1.457,3.289,5.049,5.149,8.617,4.34c1.344-0.307,2.619-0.983,3.658-2.031
    3737            l9.621-9.695c2.92-2.941,2.904-7.713-0.041-10.635c-2.941-2.92-7.713-2.902-10.635,0.041l-2.967,2.988
    38             c-2.71-1.063-5.618-1.48-8.483-1.256l6.547-6.597c5.611-5.655,14.748-5.688,20.402-0.075c5.658,5.61,5.693,14.744,0.08,20.401
    39             L42.242,995.447z M26.966,1010.849l6.547-6.598c-2.868,0.225-5.776-0.195-8.487-1.259l-2.966,2.989
    40             c-2.922,2.943-7.689,2.963-10.637,0.04c-2.94-2.919-2.962-7.69-0.038-10.636l9.621-9.694c2.931-2.954,7.708-2.946,10.635-0.04
     38            c-2.711-1.063-5.617-1.48-8.482-1.256l6.547-6.597c5.611-5.655,14.748-5.688,20.402-0.075c5.658,5.61,5.693,14.744,0.08,20.401
     39            L42.242,995.447z M26.967,1010.849l6.547-6.598c-2.867,0.225-5.775-0.195-8.486-1.259l-2.967,2.989
     40            c-2.922,2.943-7.689,2.963-10.637,0.04c-2.939-2.919-2.961-7.69-0.037-10.636l9.621-9.694c2.93-2.954,7.707-2.946,10.635-0.04
    4141            c0.682,0.677,1.271,1.52,1.639,2.351l5.021-5.058c-0.533-0.802-1.084-1.49-1.797-2.195c-1.83-1.818-4.154-3.167-6.824-3.797
    42             c-3.465-0.82-7.169-0.344-10.345,1.424c-1.161,0.646-2.249,1.461-3.232,2.451l-9.621,9.695c-5.614,5.652-5.578,14.791,0.076,20.4
    43             C12.217,1016.539,21.355,1016.503,26.966,1010.849z"/>
    44         <path id="arrow-16-icon_2_" fill="#C2C2C2" d="M48.348,1004.938v-3.728l8.764,8.75l-8.764,8.751v-3.729H29.174l10.031-10.045
     42            c-3.465-0.82-7.168-0.344-10.344,1.424c-1.162,0.646-2.25,1.461-3.232,2.451l-9.621,9.695c-5.615,5.652-5.578,14.791,0.076,20.4
     43            C12.217,1016.539,21.355,1016.503,26.967,1010.849z"/>
     44        <path id="arrow-16-icon_3_" fill="#C2C2C2" d="M48.348,1004.938v-3.728l8.764,8.75l-8.764,8.751v-3.729H29.174l10.031-10.045
    4545            H48.348z"/>
    4646    </g>
    4747    <g>
    48         <path fill="#28A885" d="M23.153,768.877l-4.267-4.181l16.008-15.962c-2.162-1.496-3.979-3.314-4.846-4.887L4.864,769.043
    49             l4.876,4.882l4.251-4.249l4.27,4.268L23.153,768.877z"/>
    50         <path fill="#28A885" d="M48.697,730.098c-6.043-6.043-15.16-6.727-20.362-1.523c-5.201,5.202-4.52,14.318,1.523,20.363
     48        <path fill="#28A885" d="M23.152,768.877l-4.267-4.181l16.008-15.962c-2.162-1.496-3.979-3.314-4.846-4.887L4.864,769.043
     49            l4.876,4.882l4.252-4.249l4.27,4.268L23.152,768.877z"/>
     50        <path fill="#28A885" d="M48.697,730.098c-6.043-6.043-15.16-6.727-20.362-1.523c-5.201,5.202-4.521,14.318,1.523,20.363
    5151            c6.044,6.043,15.159,6.725,20.361,1.521C55.422,745.257,54.741,736.141,48.697,730.098z M34.531,744.264
    5252            c-3.045-3.046-3.389-7.639-0.767-10.26s7.214-2.278,10.259,0.767c3.045,3.046,3.389,7.639,0.767,10.26
    5353            C42.17,747.65,37.576,747.308,34.531,744.264z"/>
    5454    </g>
    55     <path fill="#2AA886" d="M34,0.03v12.673c7.996,1.806,13.868,8.895,13.868,17.388S41.996,45.674,34,47.479v12.063
     55    <path fill="#2BA886" d="M34,0.03v12.673c7.996,1.806,13.868,8.895,13.868,17.388S41.996,45.674,34,47.479v12.063
    5656        c14.994-1.936,26.073-14.498,26.073-29.757C60.073,14.528,48.994,1.966,34,0.03z"/>
    57     <path fill="#2AA886" d="M20.392,15.445c1.927-1.373,4.002-2.355,6.608-2.843V0c-5.95,0.735-11.442,3.233-15.811,6.938
     57    <path fill="#2BA886" d="M20.392,15.445c1.927-1.373,4.002-2.355,6.608-2.843V0c-5.95,0.735-11.441,3.233-15.811,6.938
    5858        L20.392,15.445z"/>
    59     <path fill="#2AA886" d="M14.053,36.771L2.034,38.942C5.553,49.918,15.217,58.131,27,59.569V47.541
    60         C21.185,46.304,16.266,42.203,14.053,36.771z"/>
    61     <path fill="#2AA886" d="M6.33,11.978c-3.696,4.979-5.899,11.126-5.899,17.808c0,0.78,0.039,1.551,0.105,2.313l12.11-2.188
     59    <path fill="#2BA886" d="M14.053,36.771L2.034,38.942C5.553,49.918,15.217,58.131,27,59.569V47.541
     60        C21.186,46.304,16.266,42.203,14.053,36.771z"/>
     61    <path fill="#2BA886" d="M6.33,11.978c-3.696,4.979-5.899,11.126-5.899,17.808c0,0.78,0.039,1.551,0.105,2.313l12.11-2.188
    6262        c0.035-3.489,1.088-6.723,2.854-9.456L6.33,11.978z"/>
    6363    <g>
    6464        <ellipse fill="#28A885" cx="30.177" cy="136.379" rx="5.494" ry="4.731"/>
    65         <path fill="#28A885" d="M30.173,119.92c-13.545,0-24.534,10.99-24.534,24.539c0,13.761,11.933,22.838,24.534,35.461
    66             c12.612-12.623,24.543-21.699,24.543-35.461C54.717,130.91,43.734,119.92,30.173,119.92z M32.576,145.532l-0.029,13.558l4.21-0.04
    67             l0.083,4.963l-4.255-0.002l-0.005,4.236l-4.862-0.007l0.011-22.72c-4.845-0.959-8.461-4.689-8.458-9.149
    68             c0.003-5.185,4.89-9.385,10.913-9.379c6.024,0.004,10.903,4.211,10.899,9.396C41.081,140.859,37.441,144.592,32.576,145.532z"/>
     65        <path fill="#28A885" d="M30.174,119.92c-13.545,0-24.535,10.99-24.535,24.539c0,13.761,11.934,22.838,24.535,35.461
     66            c12.611-12.623,24.543-21.699,24.543-35.461C54.717,130.91,43.734,119.92,30.174,119.92z M32.576,145.532l-0.029,13.558l4.21-0.04
     67            l0.083,4.963l-4.255-0.002l-0.005,4.236l-4.861-0.007l0.011-22.72c-4.845-0.959-8.461-4.689-8.458-9.149
     68            c0.004-5.185,4.891-9.385,10.914-9.379c6.023,0.004,10.902,4.211,10.898,9.396C41.081,140.859,37.441,144.592,32.576,145.532z"/>
     69    </g>
     70    <g>
     71        <path fill="#28A885" d="M54.885,1109.918c-0.002-0.064-0.001-0.127-0.006-0.191c-0.021-1.113-0.511-2.206-1.459-2.941
     72            l-13.361-10.354c-1.664-1.288-4.057-0.985-5.346,0.678l-0.34,0.437c-1.289,1.665-0.986,4.059,0.679,5.348l9.064,7.024
     73            l-9.064,7.024c-1.665,1.289-1.968,3.683-0.679,5.348l0.34,0.437c1.289,1.663,3.682,1.966,5.346,0.678l13.361-10.354
     74            c0.948-0.736,1.438-1.828,1.459-2.941C54.884,1110.045,54.883,1109.982,54.885,1109.918z"/>
     75        <path fill="#28A885" d="M4.797,1109.918c0.002-0.064,0.001-0.127,0.006-0.191c0.021-1.113,0.511-2.206,1.459-2.941l13.361-10.354
     76            c1.664-1.288,4.057-0.985,5.346,0.678l0.34,0.437c1.289,1.665,0.986,4.059-0.679,5.348l-9.064,7.024l9.064,7.024
     77            c1.665,1.289,1.968,3.683,0.679,5.348l-0.34,0.437c-1.289,1.663-3.682,1.966-5.346,0.678l-13.361-10.354
     78            c-0.948-0.736-1.438-1.828-1.459-2.941C4.798,1110.045,4.799,1109.982,4.797,1109.918z"/>
    6979    </g>
    7080</g>
  • expresscurate/trunk/js/Buttons.js

    r1115335 r1129694  
    11var ExpressCurateButtons = (function ($) {
     2    var postAnalysisTimer = false;
     3
    24    function textboxCommand(ed, elem, cssClass, isVal) {
    35        var id = elem,
     
    106108    }
    107109
    108     function postAnalysis(ed, dialog) {
    109         ExpressCurateUtils.track('/post/content/seo/analytics');
     110    function postAnalysis(ed, scroll) {
     111        var $postAnalysisTab = $('.expresscurate_advancedSEO_widget .postAnalysisTab'),
     112            apended = false;
    110113
    111114        var lengthMessage, lengthColor,
     
    113116            content = (($contentWrap.css("display") === "block") ? $contentWrap.val() : tinyMCE.get("content").getContent()),
    114117            wordsCount = ExpressCurateSEOControl.wordsInText(content).length,
    115             messageHtml;
     118            messageHtml,
     119            notificationCount = 0;
    116120
    117121
     
    181185
    182186        if (defKeywords.length > 0) {
     187            apended = true;
    183188            var keywordsArray = defKeywords.split(', ');
    184189
     
    200205                messageHtml += containsAtLeastOne($(content)[0].innerHTML, keywordsArray) ? '' : '<p class="lengthSuggestion blue">No keyword appear in the first paragraph, add one if appropriate.</p>';
    201206            }
    202         }
    203         if (dialog) {
    204             ed.windowManager.open({
    205                 title: 'Post Analysis',
    206                 id: 'expresscurate_wordCount_dialog',
    207                 width: 450,
    208                 html: messageHtml
    209             });
    210         }
    211         $('.expresscurate_advancedSEO_widget .postAnalysisTab').empty().append(messageHtml);
     207            var postKeywords = [],
     208                $keywordsBoxes = $('.expresscurate_background_wrap');
     209            $.each($keywordsBoxes, function (index, value) {
     210                var $keywordWrap = $(value).find('.statisticsTitle'),
     211                    item = {
     212                        keyword: $keywordWrap.find('span').text().toLowerCase(),
     213                        color: $keywordWrap.data('color'),
     214                        count: $(value).find('.statistics .center span').text().slice(0, -1)
     215                    };
     216                postKeywords.push(item);
     217            });
     218            var firstUse = false,
     219                optimizedUse = false;
     220            $.ajax({
     221                type: 'POST',
     222                url: 'admin-ajax.php?action=expresscurate_get_post_analytics_stats'
     223            }).success(function (res) {
     224                var data = $.parseJSON(res);
     225                $.each(data, function (index, value) {
     226                    var color = value.color;
     227                    for (var i = 0; i < postKeywords.length; i++) {
     228                        if (postKeywords[i].keyword.toLowerCase() == index) {
     229                            if (postKeywords[i].color === 'green' && color === 'blue') {
     230                                firstUse = true;
     231                            }
     232                            if (value.percent == 0 && postKeywords[i].count > 0.00) {
     233                                optimizedUse = true;
     234                            }
     235                        }
     236                    }
     237                });
     238            }).always(function () {
     239                messageHtml += (firstUse) ? '<p class="lengthSuggestion green">Good job! You optimized the keyword with low usage in this post!</p>' : '';
     240                messageHtml += (optimizedUse) ? '<p class="lengthSuggestion green">Good job! It’s the first time you use this focus keyword!</p>' : '';
     241                $postAnalysisTab.empty().append(messageHtml);
     242                notificationCount = $postAnalysisTab.find('p.red').length;
     243                $('#expresscurate_post_analysis_notification').val(notificationCount);
     244            });
     245        }
     246        if (scroll) {
     247            $('.expresscurate_advancedSEO_widget ul.tabs li').add($('.tab-content')).removeClass('current');
     248            $postAnalysisTab.add($('.postAnalysisLink')).addClass('current');
     249
     250            $('html, body').animate({
     251                scrollTop: $("#expresscurate_advanced_seo").offset().top - 40
     252            }, 700);
     253        }
     254        if (!apended) {
     255            $postAnalysisTab.empty().append(messageHtml);
     256            notificationCount = $postAnalysisTab.find('p.red').length;
     257            $('#expresscurate_post_analysis_notification').val(notificationCount);
     258        }
     259        if (!postAnalysisTimer) {
     260            var $this = $(this);
     261            (postAnalysisRefreshInterval = function () {
     262                postAnalysisTimer = true;
     263                postAnalysis(tinymce.activeEditor, false);
     264                setTimeout(postAnalysisRefreshInterval, 60000);
     265            })();
     266        }
    212267    }
    213268
     
    250305        }
    251306    }
    252 
     307    function checkSocialTab(){
     308        var $this = $('#expresscurate_socialEmbed'),
     309            content = $this.val().trim(),
     310            $tabs = $('.expresscurate_socialDialog .tabs li');
     311        $.each($tabs, function (index, value) {
     312            var tab = $(value).data('tab'),
     313                myRegExp = new RegExp('https?:\/\/([a-zA-Z\d-]+\.){0,}' + tab + '\.com', 'gmi');
     314            if (myRegExp.test(content)) {
     315                $tabs.removeClass('current');
     316                $('.expresscurate_socialDialog .tabs li.' + tab).addClass('current');
     317            }
     318        });
     319    }
    253320    function setupButtons() {
    254         $('.postAnalysisLink').on('click', function () {
    255             var $this=$(this);
    256             postAnalysis(tinymce.activeEditor, false);
    257             (postAnalysisRefreshInterval = function () {
    258                 if ($this.hasClass('current')) {
    259                     postAnalysis(tinymce.activeEditor, false);
    260                 }
    261                 setTimeout(postAnalysisRefreshInterval, 60000);
    262             })();
    263         });
    264         $('html').on('click', '.expresscurate_postAnalysis', function () {
     321        var $page = $('html');
     322        $page.on('click', '.expresscurate_postAnalysis', function () {
     323            ExpressCurateUtils.track('/post/content/seo/analytics');
    265324            postAnalysis(tinymce.activeEditor, true);
    266325        });
     326        $page.on('hover', '#publish', function () {
     327            postAnalysis(tinymce.activeEditor, false);
     328        });
     329        $('.expresscurate_advancedSEO_widget .postAnalysisLink').on('click', function () {
     330            ExpressCurateUtils.track('/post/content/seo/analytics');
     331            postAnalysis(tinymce.activeEditor, false);
     332        });
     333        /*Embed dialog*/
     334        $page.on('keyup , blur', '#expresscurate_socialEmbed', function () {
     335            checkSocialTab();
     336        });
     337        $('#expresscurate_socialModal').on('click', function () {
     338            $contentWrap = $('#content');
     339            ($contentWrap.css("display") === "block") ? $contentWrap.focus() : tinyMCE.get("content").focus();
     340            var ed = tinymce.activeEditor;
     341            ed.windowManager.open({
     342                title: 'Embed',
     343                id: 'ExpresscurateEmbed',
     344                html: ExpressCurateUtils.getTemplate('socialPostDialog', null),
     345                width: 530,
     346                height: 180,
     347                buttons: [{
     348                    text: 'Insert',
     349                    classes: 'expresscurate_socialInsertButton',
     350                    disabled: false,
     351                    onclick: function () {
     352                        checkSocialTab();
     353                        var $input=$('#expresscurate_socialEmbed'),
     354                            insertedValue = $input.val().trim(),
     355                            selectedTab = $('.expresscurate_socialDialog .tabs li.current').data('tab');
     356                        /*if inserted content is URL*/
     357                        if (!insertedValue.match(/(<([^>]+)>)/gi) && selectedTab) {
     358                            if ($contentWrap.css("display") === "block") {
     359                                var existedContent = $contentWrap.val();
     360                                $contentWrap.val(existedContent + '[embed]' + insertedValue + '[/embed]');
     361                                ed.windowManager.close();
     362                            } else {
     363                                ed.insertContent('[embed]' + insertedValue + '[/embed]');
     364                                ed.windowManager.close();
     365                            }
     366                        } else {
     367                            var $elem,
     368                                url='';
     369                            switch (selectedTab) {
     370                                case 'facebook':
     371                                    $elem = $(insertedValue)[2];
     372                                    url = $($elem).data('href');
     373                                    break;
     374                                case 'twitter':
     375                                    $elem = $(insertedValue).find('> a');
     376                                    url = $($elem).attr('href');
     377                                    break;
     378                                case 'youtube':
     379                                    $elem = $(insertedValue);
     380                                    url = $($elem).attr('src');
     381                                    break;
     382                                case 'vimeo':
     383                                    $elem = $(insertedValue);
     384                                    url = $($elem).attr('src');
     385                                    break;
     386                            }
     387                            if (url) {
     388                                if ($contentWrap.css("display") === "block") {
     389                                    var existedText = $contentWrap.val();
     390                                    $contentWrap.val(existedText + '[embed]' + url + '[/embed]');
     391                                    ed.windowManager.close();
     392                                } else {
     393                                    ed.insertContent('[embed]' + url + '[/embed]');
     394                                    ed.windowManager.close();
     395                                }
     396                            } else {
     397                                var message='Embed code you have provided is wrong. Please check.';
     398                                ExpressCurateUtils.validationMessages(message,$('.expresscurate_socialDialog .expresscurate_errorMessage'),$input);
     399                                /*The tab/ URL/ embed code you have provided is wrong. Please check.*/
     400                            }
     401                        }
     402                    }
     403                }]
     404            });
     405        });
     406        /*$page.on('click', '.expresscurate_socialDialog .tabs li', function () {
     407            $('.expresscurate_socialDialog .tabs li').removeClass('current');
     408            $(this).addClass('current');
     409        });*/
    267410        tinymce.create('tinymce.plugins.expresscurate', {
    268411            /**
     
    275418             */
    276419
    277             visualizeShortcode: function (co) {
    278                 return co.replace(/\[facebook([^\]]*)\]/g, function (a, b) {
    279                     return '<img src="" class="expresscurate_FacebookEmbed" title="facebook' + tinymce.DOM.encode(b) + '" />';
    280                 });
    281             },
    282 
    283             recoverShortcode: function (co) {
    284                 function getAttr(s, n) {
    285                     n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);
    286                     return n ? tinymce.DOM.decode(n[1]) : '';
    287                 }
    288 
    289                 return co.replace(/(?:<p[^>]*>)*(<img[^>]+>)(?:<\/p>)*/g, function (a, im) {
    290                     var cls = getAttr(im, 'class');
    291                     if (cls.indexOf('expresscurate_FacebookEmbed') != -1) {
    292                         return '<p>[' + tinymce.trim(getAttr(im, 'title')) + ']</p>';
    293                     }
    294                     return a;
    295                 });
    296             },
    297420            init: function (ed, url) {
    298                 /* var t = this;
    299                  t.url = url;
    300                  //replace shortcode before editor content set
    301                  ed.onBeforeSetContent.add(function (ed, o) {
    302                  o.content = t.visualizeShortcode(o.content);
    303                  });
    304                  //replace shortcode as its inserted into editor
    305                  ed.onExecCommand.add(function (ed, cmd) {
    306                  if (cmd === 'mceInsertContent') {
    307                  tinyMCE.activeEditor.setContent(t.visualizeShortcode(tinyMCE.activeEditor.getContent()));
    308                  }
    309                  });
    310                  //replace the image back to shortcode on save
    311                  ed.onPostProcess.add(function (ed, o) {
    312                  if (o.get)
    313                  o.content = t.recoverShortcode(o.content);
    314                  });*/
    315 
    316421                // Register buttons - trigger above command when clicked
    317422                ed.addButton('sochalPost', {
     
    402507                    if (e.altKey && e.keyCode === 87) {     // alt+w
    403508                        e.returnValue = false;
     509                        ExpressCurateUtils.track('/post/content/seo/analytics');
    404510                        postAnalysis(ed, true);
    405511                        e.preventDefault();
     
    487593
    488594                if (ed.id !== 'expresscurate_content_editor') {
    489                     //lefttextbox
    490595                    ed.addCommand('lefttextbox', function () {
    491596                        textboxCommand(ed, 'lefttextbox', 'expresscurate_fl_text_box');
    492597                    });
    493                     //righttextbox
    494598                    ed.addCommand('righttextbox', function () {
    495599                        textboxCommand(ed, 'righttextbox', 'expresscurate_fr_text_box');
    496600                    });
    497                     //justifytextbox
    498601                    ed.addCommand('justifytextbox', function () {
    499602                        textboxCommand(ed, 'justifytextbox', 'expresscurate_justify_text_box');
    500603                    });
    501                     //annotation
    502604                    ed.addCommand('annotation', function (ui, val) {
    503605                        textboxCommand(ed, 'annotation', 'expresscurate_annotate', val);
     
    560662                isSetup = true;
    561663            }
    562         }
     664        },
     665        postAnalysis: postAnalysis
    563666    }
    564667})(window.jQuery);
  • expresscurate/trunk/js/Dialog.js

    r1115335 r1129694  
    152152            var data = {
    153153                index: index,
    154                 tag: value
     154                tag: $("<div/>").html(value).text()
    155155            };
    156156            keywordsHTML += ExpressCurateUtils.getTemplate('dialogCuratedtags', data);
     
    259259
    260260    function exportAPICheckImages(images) {
     261
    261262        var errorHTML;
    262263        $.ajax({
     
    288289
    289290    function exportAPIDownloadImages(images, postID) {
     291
    290292        var errorHTML;
    291293        $.ajax({
     
    338340            data: $url.serialize()
    339341        }).done(function (res) {
     342
    340343            var data = $.parseJSON(res);
    341344            if (data) {
     
    397400        $dialog.on('click', '#curated_description', function () {
    398401            insertText('curated_description', 'p');
     402        });
     403        $dialog.on('click', function (e) {
     404            if(!$(e.target).is('.autoComplete li')){
     405                $dialog.find('.autoComplete').remove();
     406            }
    399407        });
    400408        $('.nextSlide').click(function () {
     
    555563                        domain = domain.match(/^(http|https)/) ? domain : 'http://' + domain;
    556564                        if (domain) {
    557                             html += '<cite><p class="expresscurate_source">' + $("#expresscurate_from").val() + ' <cite><a class="expresscurated" rel="nofollow" data-curated-url="' + domain + '"  href = "' + domain + '">' + title + '</a></p></cite><br/>';
     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/>';
    558566                        }
    559567                    }
     
    624632                displayCuratedParagraphs($curatedParagraphs, $curatedParagraphs.length, true);
    625633            }
     634        });
     635        html.on('keyup', '#expresscurate_source', function () {
     636            var input = $(this),
     637                liHTML = '',
     638                list = $('.expresscurate_dialog .autoComplete');
     639            if (input.val().length > 1) {
     640                $.ajax({
     641                    type: 'POST',
     642                    url: 'admin-ajax.php?action=expresscurate_search_feed_bookmark',
     643                    data: {searchKeyword: input.val()}
     644                }).done(function (res) {
     645                    var data = $.parseJSON(res);
     646                    $.each(data.slice(0, 5), function (key, value) {
     647                        liHTML += '<li data-link="' + value.link + '">' + value.title + '</li>';
     648                    });
     649                    if (liHTML.length > 0) {
     650                        input.after('<ul class="autoComplete">' + liHTML + '</ul>');
     651                    } else {
     652                        list.remove();
     653                    }
     654                });
     655
     656            } else {
     657                list.remove();
     658            }
     659        });
     660        html.on('click', '.expresscurate_dialog .autoComplete li', function () {
     661            var li = $(this);
     662            $('#expresscurate_source').val(li.data('link'));
     663            $('#curated_title').val(li.text());
     664            $('.expresscurate_dialog .autoComplete').remove();
    626665        });
    627666    }
     
    665704                    }, 0);
    666705                });
    667                 html.on('keyup', '#expresscurate_source', function () {
    668                     var input = $(this),
    669                         liHTML = '',
    670                         list = $('.expresscurate_dialog .autoComplete');
    671                     if (input.val().length > 1) {
    672                         $.ajax({
    673                             type: 'POST',
    674                             url: 'admin-ajax.php?action=expresscurate_search_feed_bookmark',
    675                             data: {searchKeyword: input.val()}
    676                         }).done(function (res) {
    677                             var data = $.parseJSON(res);
    678                             $.each(data.slice(0, 5), function (key, value) {
    679                                 liHTML += '<li data-link="' + value.link + '">' + value.title + '</li>';
    680                             });
    681                             if (liHTML.length > 0) {
    682                                 input.after('<ul class="autoComplete">' + liHTML + '</ul>');
    683                             } else {
    684                                 list.remove();
    685                             }
    686                         });
    687 
    688                     } else {
    689                         list.remove();
    690                     }
    691                 });
    692                 html.on('click', '.expresscurate_dialog .autoComplete li', function () {
    693                     var li = $(this);
    694                     $('#expresscurate_source').val(li.data('link'));
    695                     $('#curated_title').val(li.text());
    696                     $('.expresscurate_dialog .autoComplete').remove();
    697                 });
    698706            }
    699707        },
  • expresscurate/trunk/js/Utils.js

    r1115335 r1129694  
    2929            }
    3030        }
     31    }
     32
     33    /*error messages*/
     34    function validationMessages(messageText, message, input) {
     35        $(message).text(messageText).addClass('errorActive');
     36        $(input).prop('disabled', true).blur().addClass('expresscurate_errorMessageInput');
     37        setTimeout(function () {
     38            $(message).removeClass('errorActive');
     39            setTimeout(function () {
     40                $(message).text('');
     41                $(input).removeClass('expresscurate_errorMessageInput').removeAttr('disabled').focus();
     42            }, 300);
     43        }, 3000);
    3144    }
    3245
     
    5972            regularExpression = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
    6073            validEmail = regularExpression.test(email),
    61             $messageError = $('label[for="expresscurate_support_message"]'),
    62             $mailError = $('label[for="expresscurate_support_email"]');
     74            $messageError = $('#expresscurate_support_message_validation'),
     75            $mailError = $('#expresscurate_support_email_validation');
    6376
    6477        $form.find('.expresscurate_errorMessage').text('');
     
    6679        if (msg === "" || !msg) {
    6780            validMsg = false;
    68             $messageError.text('Please enter the message');
     81            validationMessages('Please enter the message', $messageError, $supportMessage);
    6982        } else if (msg.length < 3) {
    7083            validMsg = false;
    71             $messageError.text('Message is too short');
     84            validationMessages('Message is too short', $messageError, $supportMessage);
    7285        }
    7386
    7487        if (email === "" || !email) {
    7588            validEmail = false;
    76             $mailError.text('Please enter the email');
     89            validationMessages('Please enter the email', $mailError, $supportMail);
    7790        } else if (!validEmail) {
    78             $mailError.text('Email is not valid');
     91            validationMessages('Email is not valid', $mailError, $supportMail);
    7992        }
    8093        if (validEmail && validMsg) {
     
    91104
    92105    function endLoading(input, elemToRotate) {
    93         input.removeAttr('disabled').focus();
     106        input.removeAttr('disabled');
    94107        elemToRotate.removeClass('expresscurate_startRotate');
    95108    }
     
    182195            $(document).on('change', 'select[name="_status"]', function () {
    183196                postNewStatus = this.value;
    184                 if (postOldStatus !== postNewStatus && postNewStatus === 'publish') {
    185                     track('/post-edit/publish');
     197            });
     198            $(document).on('mouseup', '.inline-edit-save .save', function () {
     199                var $this = $(this),
     200                    postId = $this.parents('tr').attr('id'),
     201                    $post = $('#post-' + postId.split('-')[1]),
     202                    curated = $post.find('.column-curated em').text();
     203                if (postOldStatus != postNewStatus && postNewStatus == 'publish' && curated == 'Yes') {
     204                    track('/post-edit/publish',true);
    186205                    postOldStatus = postOldStatus = null;
    187206                }
     
    378397        countDown: countDown,
    379398        getTemplate: getTemplate,
    380         track: track
     399        track: track,
     400        validationMessages: validationMessages
    381401    }
    382402})(window.jQuery);
  • expresscurate/trunk/js/bookmarks.js

    r1106118 r1129694  
    88            liHTML = '',
    99            message = '',
    10             $errorMessage = $(".addNewBookmark .errorMessage");
    11 
    12         $errorMessage.text('');
     10            $errorMessage = $(".addNewBookmark .expresscurate_errorMessage");
     11
     12        //$errorMessage.text('');
    1313
    1414        if (!link.match(myRegExp)) {
    1515            message = 'Invalid URL';
    16             $errorMessage.text(message);
     16            ExpressCurateUtils.validationMessages(message,$errorMessage,$input);
    1717        } else {
    1818            ExpressCurateUtils.startLoading($input, $elemToRotate);
     
    5656                }
    5757                if (message !== '') {
    58                     $errorMessage.text(message);
     58                    ExpressCurateUtils.validationMessages(message,$errorMessage,$input);
    5959                }
    6060                ExpressCurateUtils.endLoading($input, $elemToRotate);
     
    217217            ExpressCurateUtils.checkControls($controls);
    218218        });
    219         $bookmarkBoxes.on('click', '> li', function (e) {
    220             if (e.target !== this) {
    221                 return;
    222             }
    223             var checkbox = $(this).find('.checkInput');
    224             if (checkbox.is(':checked')) {
    225                 checkbox.attr('checked', false);
    226             }
    227             else {
    228                 checkbox.attr('checked', true);
    229             }
    230             ExpressCurateUtils.checkControls($controls);
    231         });
    232219        $('.expresscurate_bookmarks .check').on('click', function () {
    233220            var checked = $bookmarkBoxes.find('li input:checkbox:checked').length,
  • expresscurate/trunk/js/feed/contentFeed.js

    r1106118 r1129694  
    4848
    4949        $.each(els, function (index, el) {
    50             var item = $(el).find('textarea').val();
     50            var item = $(el).find('a.postTitle').data('fulllink');
    5151            items.push(item);
    5252        });
     
    5454            type: 'POST',
    5555            url: 'admin-ajax.php?action=expresscurate_delete_feed_content_items',
    56             data: {items: JSON.stringify(items)}
     56            data: {items: items}
    5757        }).done(function (res) {
    5858            var data = $.parseJSON(res);
     
    6767                }, 700);
    6868            }
     69        });
     70    }
     71
     72    function pullFeedManualy() {
     73        $.ajax({
     74            type: 'POST',
     75            url: 'admin-ajax.php?action=expresscurate_manual_pull_feed'
     76        }).done(function (res) {
     77            //console.log(res);
    6978        });
    7079    }
     
    8998
    9099        /*checkboxes*/
    91         $feedBoxes.on('click', '> li', function (e) {
    92             if (e.target !== this) {
    93                 return;
    94             }
    95             var $checkbox = $(this).find('.checkInput');
    96 
    97             if ($checkbox.is(':checked'))
    98                 $checkbox.attr('checked', false);
    99             else
    100                 $checkbox.attr('checked', true);
    101             ExpressCurateUtils.checkControls($feedControls);
    102         });
    103100        $feedBoxes.on('change', '.checkInput', function () {
    104101            ExpressCurateUtils.checkControls($feedControls);
     
    116113            ExpressCurateUtils.checkControls($feedControls);
    117114        });
    118 
     115        /*pull*/
     116        $('.expresscurate_feed_list .pull').on('click',function(){
     117            pullFeedManualy();
     118        });
    119119        /*delete*/
    120120        $('.expresscurate_feed_list .remove').on('click', function () {
     
    157157                var $elem = $($checked[0]).parent().find('a'),
    158158                    title = $elem.html(),
    159                     url =  window.btoa(encodeURIComponent($elem.attr('href')));
     159                    url = window.btoa(encodeURIComponent($elem.attr('href')));
    160160                window.location.href = $('#adminUrl').val() + 'post-new.php?expresscurate_load_source=' + url + '&expresscurate_load_title=' + title;
    161161            } else if ($checked.length > 1) {
  • expresscurate/trunk/js/feed/feedSettings.js

    r1106118 r1129694  
    66
    77        var message = '',
    8             link = $input.val(),
     8            link = $input.val().replace(/\/\s*$/, ""),
    99            liHTML = '',
    1010            $lastLi,
    11             $errorMessage=$(".addNewFeed .errorMessage");
     11            $errorMessage = $(".addNewFeed .expresscurate_errorMessage");
    1212
    1313        ExpressCurateUtils.startLoading($input, $elemToRotate);
    14         $errorMessage.text();
    1514
    1615        $.ajax({
     
    3433            } else {
    3534                message = data.status;
    36                 $errorMessage.text(message);
     35                ExpressCurateUtils.validationMessages(message, $errorMessage, $input);
    3736            }
    3837        }).always(function () {
     
    6564
    6665    function setupFeedSettings() {
    67         $addFeed=$('.addFeed');
     66        $addFeed = $('.addFeed');
    6867        $input = $addFeed.find('input');
    6968        $elemToRotate = $addFeed.find('span span');
  • expresscurate/trunk/js/keywords/Keywords.js

    r1106118 r1129694  
    106106                    $(val).replaceWith(this.childNodes);
    107107                });
    108                 tinyMCE.activeEditor.windowManager.open({
     108                var dialog=tinyMCE.activeEditor.windowManager.open({
    109109                    title: 'Mark keywords',
    110110                    id: 'expresscurate_keyword_dialog',
    111111                    width: 450,
    112112                    height: 80,
    113                     html: '<label class="expresscurate_keywordMessage">Currently you don&#39;t have any defined keywords.</label>  <a class="button-primary" href="#expresscurate">Start adding now</a> <a href="#" class="cancel">Cancel</a>'
     113                    html: '<label class="expresscurate_keywordMessage">Currently you don&#39;t have any defined keywords.</label> <!-- <a class="expresscurate_keywordMessageButton button-primary " href="#expresscurate">Start adding now</a> <a href="#" class="cancel">Cancel</a>-->',
     114                    buttons: [{
     115                        text: 'Start adding now',
     116                        classes: 'expresscurate_socialInsertButton',
     117                        disabled: false,
     118                        onclick: function(){
     119                            $('html, body').animate({
     120                                scrollTop: $("#expresscurate").offset().top - 40
     121                            }, 400);
     122                            dialog.close();
     123                            $('.expresscurate_widget .addKeywords input').focus();
     124                        }
     125                    }]
    114126                });
    115127            } else if (ed) {
  • expresscurate/trunk/js/keywords/SEOControlCenter.js

    r1111122 r1129694  
    55        if (keywords.length > 0) {
    66            ExpressCurateUtils.track('/post/seo-control-center/keyword/add');
    7 
    87            updateKeywords();
    98        }
     
    270269            }
    271270        });
     271        $('.expresscurate_moveToAdvanced').on('click',function(){
     272            $('html, body').animate({
     273                scrollTop: $("#expresscurate_advanced_seo").offset().top - 40
     274            }, 700);
     275        })
    272276    }
    273277
  • expresscurate/trunk/readme.txt

    r1115335 r1129694  
    55Requires at least: 3.9
    66Tested up to: 4.1
    7 Stable tag: 2.0.9
     7Stable tag: 2.0.10
    88License: GPLv3 or later
    99License URI: http://www.gnu.org/licenses/gpl.html
     
    8181
    8282= How To Get Started =
    83 [Download ExpressCurate plugin](http://downloads.wordpress.org/plugin/expresscurate.2.0.9.zip "Your favorite content marketing tools") for WordPress. 
     83[Download ExpressCurate plugin](http://downloads.wordpress.org/plugin/expresscurate.2.0.10.zip "Your favorite content marketing tools") for WordPress. 
    8484You 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.
    8585
     
    129129== Changelog ==
    130130
     131= 2.0.10 =
     132* 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.
     133* Content Feed performance improvements.
     134* Bug fixation for SEO meta robots=follow-nofollow, index-noidex
     135* Other miscellaneous bug fixes and improvements.
     136
    131137= 2.0.9 =
    132138* Miscellaneous bug fixes and improvements.
  • expresscurate/trunk/templates/advanced_seo_widget.php

    r1115335 r1129694  
    66
    77<div class="container expresscurate_Styles expresscurate_advancedSEO_widget">
    8 
     8    <input type="hidden" name="expresscurate_post_analysis_notification" value="0" id="expresscurate_post_analysis_notification"/>
    99<ul class="tabs">
    1010    <li class="tab-link expresscurate_preventTextSelection green current" data-tab="tab-1">General</li>
  • expresscurate/trunk/templates/bookmarks.php

    r1115352 r1129694  
    5151            <div class="addBookmark">
    5252                <input id="addBookmark" type="text" placeholder="URL" class="expresscurate_disableInputStyle"/>
    53                 <span class="expresscurate_preventTextSelection"><span></span></span>
     53                <span class="plus expresscurate_preventTextSelection"><span></span></span>
     54                <span class="expresscurate_errorMessage"></span>
    5455            </div>
    55             <span class="errorMessage"></span>
    5656
    5757            <div class="expresscurate_clear"></div>
    58             <p><span></span></p>
    5958        </div>
    6059        <?php
     
    9897
    9998                    <a class="postTitle" href="<?php echo $item['link'] ?>"
    100                        target="_newtab"><?php echo $item['title'] ?></a><br/>
    101                     <a class="url" href="<?php echo $item['link'] ?>"><?php echo $item['domain'] ?></a>
     99                       target="_blank"><?php echo $item['title'] ?></a><br/>
     100                    <a class="url" target="_blank" href="<?php echo $item['link'] ?>"><?php echo $item['domain'] ?></a>
    102101                    <!--<span class="curatedBy">/<?php /*echo $item['curated'] ? 'curated by' : 'author'; */ ?> <span><?php /*echo $item['author']; */ ?></span> /</span>-->
    103102                    <span class="curatedBy">/ by <span><?php echo $item['user']; ?></span> /</span>
     
    109108                            echo 'active';
    110109                        } ?>"
    111                                for="comment__<?php echo $i ?>"><?php echo $item['comment'] ? $item['comment'] : 'add comment'; ?></label>
     110                               for="comment__<?php echo $i ?>"><?php echo $item['comment'] ? stripslashes($item['comment']) : 'add comment'; ?></label>
    112111                        <input type="text" class="expresscurate_disableInputStyle expresscurate_displayNone"
    113                                id="comment__<?php echo $i ?>" value="<?php echo $item['comment'] ?>">
     112                               id="comment__<?php echo $i ?>" value="<?php echo stripslashes( $item['comment']); ?>">
    114113                        <span class="expresscurate_displayNone">&#215</span>
    115114                    </div>
     
    140139    </form>
    141140    <script type="text/html" id="tmpl-bookmarksItem">
     141        <!--<# for(i=0;i<data.media.images;i++) { #>
     142            <# } #>-->
    142143        <li class="expresscurate_preventTextSelection expresscurate_masonryItem">
    143144            <input id="uniqueId_{{data.id}}" class="checkInput" type="checkbox"/>
     
    145146            <ul class="keywords">
    146147                <# if (data.media.videos) { #>
    147                     <li class="media videos"><span class="tooltip">{{data.media.videos}}</span></li>
     148                    <li class="media videos"><span class="tooltip">Video(s): {{data.media.videos}}</span></li>
    148149                <# } #>
    149150                <# if (data.media.images) { #>
    150                     <li class="media images"><span class="tooltip">{{data.media.images}}</span></li>
     151                    <li class="media images"><span class="tooltip">Image(s): {{data.media.images}}</span></li>
    151152                <# } #>
    152153            </ul>
    153             <a class="postTitle" href="{{data.link}}" target="_newtab">{{data.title}}</a><br/>
    154             <a class="url" href="{{data.link}}" target="_newtab">{{data.domain}}</a>
     154            <a class="postTitle" href="{{data.link}}" target="_blank">{{data.title}}</a><br/>
     155            <a class="url" href="{{data.link}}" target="_blank">{{data.domain}}</a>
    155156            <span class="curatedBy">/ by <span>{{data.user}}</span> /</span>
    156157            <span class="time">Just now</span>
  • expresscurate/trunk/templates/dashboard.php

    r1109426 r1129694  
    66    $user_email = $current_user->user_email;
    77}
    8 if(isset($_GET['type']) && $_GET['type']=='keywords'){
     8if (isset($_GET['type']) && $_GET['type'] == 'keywords') {
    99    $msg_placeholder = 'Please, write your suggestions here ...';
    1010}
     
    2121    <div class="expresscurate_headBorderBottom expresscurate_OpenSansRegular">
    2222        <a href="admin.php?page=expresscurate&type=keywords" class="expresscurate_writeUs">Suggestions? <span>Submit here!</span></a>
     23
    2324        <h2>ExpressCurate</h2>
    2425        <label></label>
    2526    </div>
    2627    <div class="expresscurate_blocksContainer expresscurate_masonryWrap">
    27          <?php
    28                 $dashboard_order = get_option('dashboard_items_order');
    29                 if(!empty($dashboard_order)){
    30                     foreach($dashboard_order as $ordered_item):
    31                             if($ordered_item=="keyWords"):
    32                                 echo '<div id="keyWords" class="expresscurate_keywordsBlock expresscurate_masonryItem">
     28        <?php
     29        $dashboard_order = get_option('dashboard_items_order');
     30        if (!empty($dashboard_order)) {
     31            foreach ($dashboard_order as $ordered_item):
     32                if ($ordered_item == "keyWords"):
     33                    echo '<div id="keyWords" class="expresscurate_keywordsBlock expresscurate_masonryItem">
    3334                                            <label class="label">Keywords Summary</label>';
    34                                             $this->keywords_widget();
    35                                        echo '</div>';
    36                             endif;
    37                             if($ordered_item=="keyWordsIntOverTime"):
    38                                 echo '<div id="keyWordsIntOverTime" class="expresscurate_keywordsBlock expresscurate_masonryItem">
     35                    $this->keywords_widget();
     36                    echo '</div>';
     37                endif;
     38                if ($ordered_item == "keyWordsIntOverTime"):
     39                    echo '<div id="keyWordsIntOverTime" class="expresscurate_keywordsBlock expresscurate_masonryItem">
    3940                                        <label class="label">Keywords Interest Over Time</label>';
    40                                         $this->keywords_interest_over_time_widget();
    41                                      echo '</div>';
    42                             endif;
    43                             if($ordered_item=="keyWordsRelTopics"):
    44                                 echo '<div id="keyWordsRelTopics" class="expresscurate_keywordsBlock expresscurate_masonryItem">
     41                    $this->keywords_interest_over_time_widget();
     42                    echo '</div>';
     43                endif;
     44                if ($ordered_item == "keyWordsRelTopics"):
     45                    echo '<div id="keyWordsRelTopics" class="expresscurate_keywordsBlock expresscurate_masonryItem">
    4546                                        <label class="label">Keywords Related Topics</label>';
    46                                         $this->keywords_related_topics_widget();
    47                                     echo '</div>';
    48                             endif;
    49                             if($ordered_item=="smartPublish"):
    50                                 if (get_option('expresscurate_publish', '') == "on") {
    51                                     echo '<div id="smartPublish" class="expresscurate_smartPublishBlock expresscurate_masonryItem">
     47                    $this->keywords_related_topics_widget();
     48                    echo '</div>';
     49                endif;
     50                if ($ordered_item == "smartPublish"):
     51                    if (get_option('expresscurate_publish', '') == "on") {
     52                        echo '<div id="smartPublish" class="expresscurate_smartPublishBlock expresscurate_masonryItem">
    5253                                            <label class="label">Smart Publishing Overview</label>';
    53                                             $this->smart_publishing_widget();
    54                                          echo '</div>';
    55                                 }
    56                             endif;
    57                             if($ordered_item=="feedWidget"):
    58                                  echo '<div id="feedWidget" class="expresscurate_feedBlock expresscurate_masonryItem">
     54                        $this->smart_publishing_widget();
     55                        echo '</div>';
     56                    }
     57                endif;
     58                if ($ordered_item == "feedWidget"):
     59                    echo '<div id="feedWidget" class="expresscurate_feedBlock expresscurate_masonryItem">
    5960                                            <label class="label">Feed</label>';
    60                                             $this->feed_widget();
    61                                        echo '</div>';
    62                             endif;
    63                             if($ordered_item=="bookmarks"):
    64                                     echo '<div id="bookmarks" class="expresscurate_bookmarksBlock expresscurate_masonryItem">
     61                    $this->feed_widget();
     62                    echo '</div>';
     63                endif;
     64                if ($ordered_item == "bookmarks"):
     65                    echo '<div id="bookmarks" class="expresscurate_bookmarksBlock expresscurate_masonryItem">
    6566                                            <label class="label">Bookmarks</label>';
    66                                             $this->bookmarks_widget();
    67                                     echo '</div>';
    68                             endif;
    69                             if($ordered_item=="support"):
    70                                 echo '<div id="support" class="expresscurate_supportBlock expresscurate_masonryItem">
     67                    $this->bookmarks_widget();
     68                    echo '</div>';
     69                endif;
     70                if ($ordered_item == "support"):
     71                    echo '<div id="support" class="expresscurate_supportBlock expresscurate_masonryItem">
    7172                                        <label class="label">Support</label><div>';
    72                                 if(!$sent){  echo '<label for="expresscurate_support_email">Leave your feedback</label>'; } else { echo '<label for="expresscurate_support_email">Thanks for your feedback</label>'; }
    73                                 echo  '<form method="post" action="'.get_admin_url().'admin.php?page=expresscurate"
     73                    if (!$sent) {
     74                        echo '<label for="expresscurate_support_email">Leave your feedback</label>';
     75                    } else {
     76                        echo '<label for="expresscurate_support_email">Thanks for your feedback</label>';
     77                    }
     78                    echo '<form method="post" action="' . get_admin_url() . 'admin.php?page=expresscurate"
    7479                                                  id="expresscurate_support_form">
    75                                                 <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle" placeholder="Email"
    76                                                        value="'.$user_email.'"/>
    77                                                        <label for="expresscurate_support_email" class="expresscurate_errorMessage"></label>
    78                                         <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
    79                                                   placeholder="Message"></textarea>
    80                                                   <label for="expresscurate_support_message" class="expresscurate_errorMessage"></label>
     80                                                <div class="errorMessageWrap">
     81                    <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle"
     82                           placeholder="Email"
     83                           value="' . $user_email . '"/>
     84                    <span id="expresscurate_support_email_validation" class="expresscurate_errorMessage"></span>
     85                </div>
     86                                       <div class="errorMessageWrap">
     87               <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
     88                         placeholder="' . $msg_placeholder . '"></textarea>
     89                    <span class="expresscurate_errorMessage" id="expresscurate_support_message_validation"></span>
     90                </div>
    8191                                                <a class="feedbackButton send greenBackground" href="#">Send</a>
    8292                                            </form>
    8393                                        </div>
    8494                                    </div>';
    85                             endif;
    86                     endforeach;
    87                 }
    88             else {
    89          ?>
    90                 <div id ='keyWords' class="expresscurate_keywordsBlock expresscurate_masonryItem">
    91                     <label class="label">Keywords Summary</label>
    92                     <?php $this->keywords_widget(); ?>
     95                endif;
     96            endforeach;
     97        } else {
     98            ?>
     99            <div id='keyWords' class="expresscurate_keywordsBlock expresscurate_masonryItem">
     100                <label class="label">Keywords Summary</label>
     101                <?php $this->keywords_widget(); ?>
     102            </div>
     103
     104            <div id='keyWordsIntOverTime' class="expresscurate_keywordsBlock expresscurate_masonryItem">
     105                <label class="label">Keywords Interest Over Time</label>
     106                <?php $this->keywords_interest_over_time_widget(); ?>
     107            </div>
     108
     109            <div id='keyWordsRelTopics' class="expresscurate_keywordsBlock expresscurate_masonryItem">
     110                <label class="label">Keywords Related Topics</label>
     111                <?php $this->keywords_related_topics_widget(); ?>
     112            </div>
     113
     114            <?php
     115            if (get_option('expresscurate_publish', '') == "on") { ?>
     116                <div id="smartPublish" class="expresscurate_smartPublishBlock expresscurate_masonryItem">
     117                    <label class="label">Smart Publishing Overview</label>
     118                    <?php $this->smart_publishing_widget(); ?>
    93119                </div>
     120            <?php } ?>
    94121
    95                 <div id ='keyWordsIntOverTime' class="expresscurate_keywordsBlock expresscurate_masonryItem">
    96                     <label class="label">Keywords Interest Over Time</label>
    97                     <?php $this->keywords_interest_over_time_widget(); ?>
    98                 </div>
     122            <div id="feedWidget" class="expresscurate_feedBlock expresscurate_masonryItem">
     123                <label class="label">Feed</label>
     124                <?php $this->feed_widget(); ?>
     125            </div>
    99126
    100                 <div id ='keyWordsRelTopics' class="expresscurate_keywordsBlock expresscurate_masonryItem">
    101                     <label class="label">Keywords Related Topics</label>
    102                     <?php $this->keywords_related_topics_widget(); ?>
    103                 </div>
    104 
    105                 <?php
    106                 if (get_option('expresscurate_publish', '') == "on") { ?>
    107                     <div id="smartPublish" class="expresscurate_smartPublishBlock expresscurate_masonryItem">
    108                         <label class="label">Smart Publishing Overview</label>
    109                         <?php $this->smart_publishing_widget(); ?>
    110                     </div>
    111                 <?php } ?>
    112 
    113                 <div id="feedWidget" class="expresscurate_feedBlock expresscurate_masonryItem">
    114                     <label class="label">Feed</label>
    115                     <?php $this->feed_widget();?>
    116                 </div>
    117 
    118                 <div id="bookmarks" class="expresscurate_bookmarksBlock expresscurate_masonryItem">
    119                     <label class="label">Bookmarks</label>
    120                     <?php $this->bookmarks_widget();?>
    121                 </div>
     127            <div id="bookmarks" class="expresscurate_bookmarksBlock expresscurate_masonryItem">
     128                <label class="label">Bookmarks</label>
     129                <?php $this->bookmarks_widget(); ?>
     130            </div>
    122131
    123132
    124                 <div id ='support' class="expresscurate_supportBlock expresscurate_masonryItem">
    125                     <label class="label">Support</label>
    126                     <div>
    127                         <?php if (!$sent) { ?>
    128                             <label for="expresscurate_support_email">Leave your feedback</label>
    129                         <?php
    130                         } else {
    131                             ?>
    132                             <label for="expresscurate_support_email">Thanks for your feedback</label>
    133                         <?php
    134                         }
     133            <div id='support' class="expresscurate_supportBlock expresscurate_masonryItem">
     134                <label class="label">Support</label>
     135
     136                <div>
     137                    <?php if (!$sent) { ?>
     138                        <label for="expresscurate_support_email">Leave your feedback</label>
     139                    <?php
     140                    } else {
    135141                        ?>
    136                         <form method="post" action="<?php echo get_admin_url() ?>admin.php?page=expresscurate"
    137                               id="expresscurate_support_form">
    138                             <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle" placeholder="Email"
    139                                    value="<?php echo $user_email ?>"/>
    140                             <label for="expresscurate_support_email" class="expresscurate_errorMessage"></label>
     142                        <label for="expresscurate_support_email">Thanks for your feedback</label>
     143                    <?php
     144                    }
     145                    ?>
     146                    <form method="post" action="<?php echo get_admin_url() ?>admin.php?page=expresscurate"
     147                          id="expresscurate_support_form">
     148                        <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle"
     149                               placeholder="Email"
     150                               value="<?php echo $user_email ?>"/>
     151                        <label for="expresscurate_support_email" class="expresscurate_errorMessage"></label>
    141152                    <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
    142153                              placeholder="Message"></textarea>
    143                             <label for="expresscurate_support_message" class="expresscurate_errorMessage"></label>
    144                             <a class="feedbackButton send greenBackground" href="#">Send</a>
    145                         </form>
    146                     </div>
     154                        <label for="expresscurate_support_message" class="expresscurate_errorMessage"></label>
     155                        <a class="feedbackButton send greenBackground" href="#">Send</a>
     156                    </form>
    147157                </div>
    148          <?php
    149             }
     158            </div>
     159        <?php
     160        }
    150161        ?>
    151162
  • expresscurate/trunk/templates/dialog.php

    r1106118 r1129694  
    9595      <input type="hidden" value="<?php echo get_option('expresscurate_autosummary', 5); ?>" id="expresscurate_autosummary" name="expresscurate_autosummary"/>
    9696      <ul class="labels" id="curated_tags">
    97           <li class="markButton expresscurate_preventTextSelection"><span>mark keywords</span></li>
     97          <li class="markButton expresscurate_displayNone expresscurate_preventTextSelection"><span>mark keywords</span></li>
    9898      </ul>
    9999      <div class="clear"></div>
     
    139139    <li id="curated_description" title="{{data}}">Description</li>
    140140</script>
     141<script type="text/html" id="tmpl-socialPostDialog">
     142    <div class="expresscurate_socialDialog">
     143        <ul class="tabs">
     144            <li class="expresscurate_preventTextSelection facebook" data-tab="facebook"></li>
     145            <li class="expresscurate_preventTextSelection twitter" data-tab="twitter"></li>
     146            <li class="expresscurate_preventTextSelection youtube" data-tab="youtube"></li>
     147            <li class="expresscurate_preventTextSelection vimeo" data-tab="vimeo"></li>
     148        </ul>
     149        <div id="" class="tab-content">
     150            <textarea id="expresscurate_socialEmbed" placeholder="Embed code" class="expresscurate_disableInputStyle"></textarea>
     151            <span class="expresscurate_errorMessage"></span>
     152        </div>
     153    </div>
     154</script>
  • expresscurate/trunk/templates/faq.php

    r1109426 r1129694  
    44$user_email = '';
    55if ($current_user->user_email) {
    6   $user_email = $current_user->user_email;
     6    $user_email = $current_user->user_email;
    77}
    88$sent = false;
    99if ($_POST) {
    10   if ($_POST['expresscurate_support_email'] && $_POST['expresscurate_support_message']) {
    11       $expressCurateEmail = new ExpressCurate_Email();
    12       $sent =  $expressCurateEmail->sendSupportEmail($_POST['expresscurate_support_email'], 'Expresscurate FAQ',stripslashes($_POST['expresscurate_support_message']));
    13       unset($_POST);
    14   }
     10    if ($_POST['expresscurate_support_email'] && $_POST['expresscurate_support_message']) {
     11        $expressCurateEmail = new ExpressCurate_Email();
     12        $sent = $expressCurateEmail->sendSupportEmail($_POST['expresscurate_support_email'], 'Expresscurate FAQ', stripslashes($_POST['expresscurate_support_message']));
     13        unset($_POST);
     14    }
    1515}
    1616$feed = ExpressCurate_Actions::getCurationNews('http://news.expresscurate.com/category/faq/feed/');
     
    2424        <!--<label>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sagittis nulla lectus,</label>-->
    2525    </div>
    26   <h2 class="expresscurate_displayNone">FAQ</h2>
     26    <h2 class="expresscurate_displayNone">FAQ</h2>
    2727
    28   <div>
    29     <div class="block questions">
    30       <?php
    31       if (count($feed) > 0) {
    32         for ($x = 0; $x < $limit; $x++) {
    33           $title = str_replace(' & ', ' &amp; ', $feed[$x]['title']);
    34           $link = $feed[$x]['link'];
    35           ?>
    36           <div class="inlineBlock">
    37             <a class="questionBox" href="<?php echo $link ?>" target="_blank"><span><?php echo $title ?></span></a>
    38           </div>
    39           <?php
    40         }
    41         ?>
    42         <div class="inlineBlock">
    43           <a class="questionBox moreQuestions" href="http://news.expresscurate.com/category/faq/" target="_blank"><span>More questions</span></a>
     28    <div>
     29        <div class="block questions">
     30            <?php
     31            if (count($feed) > 0) {
     32                for ($x = 0; $x < $limit; $x++) {
     33                    $title = str_replace(' & ', ' &amp; ', $feed[$x]['title']);
     34                    $link = $feed[$x]['link'];
     35                    ?>
     36                    <div class="inlineBlock">
     37                        <a class="questionBox" href="<?php echo $link ?>"
     38                           target="_blank"><span><?php echo $title ?></span></a>
     39                    </div>
     40                <?php
     41                }
     42                ?>
     43                <div class="inlineBlock">
     44                    <a class="questionBox moreQuestions" href="http://news.expresscurate.com/category/faq/"
     45                       target="_blank"><span>More questions</span></a>
     46                </div>
     47            <?php } else {
     48                ?>
     49                <div class="inlineBlock">
     50                    <a class="questionBox moreQuestions" href="http://news.expresscurate.com/category/faq/"
     51                       target="_blank"><span>Visit our faq blog</span></a>
     52                </div>
     53            <?php }
     54            ?>
    4455        </div>
    45       <?php } else {
    46         ?>
    47         <div class="inlineBlock">
    48           <a class="questionBox moreQuestions" href="http://news.expresscurate.com/category/faq/" target="_blank"><span>Visit our faq blog</span></a>
    49         </div>
    50         <?php }
    51       ?>
    52     </div>
    53     <div class="block">
    54       <?php if (!$sent) { ?>
    55         <label for="expresscurate_support_email">Ask a question</label>
    56         <?php
    57       } else {
    58         ?>
    59         <label for="expresscurate_support_email">Your question has been sent</label>
    60         <?php
    61       }
    62       ?>
    63       <form method="post" action=""  id="expresscurate_support_form">
    64         <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle"
    65                placeholder="Email"
    66                value="<?php echo $user_email ?>"/>
    67         <label for="expresscurate_support_email" class="expresscurate_errorMessage"></label>
     56        <div class="block">
     57            <?php if (!$sent) { ?>
     58                <label for="expresscurate_support_email">Ask a question</label>
     59            <?php
     60            } else {
     61                ?>
     62                <label for="expresscurate_support_email">Your question has been sent</label>
     63            <?php
     64            }
     65            ?>
     66            <form method="post" action="" id="expresscurate_support_form">
     67                <div class="errorMessageWrap">
     68                    <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle"
     69                           placeholder="Email"
     70                           value="<?php echo $user_email ?>"/>
     71                    <span id="expresscurate_support_email_validation" class="expresscurate_errorMessage"></span>
     72                </div>
     73                <div class="errorMessageWrap">
    6874        <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
    6975                  placeholder="Question"></textarea>
    70         <label for="expresscurate_support_message" class="expresscurate_errorMessage"></label>
    71         <a class="askButton send greenBackground" href="#">Ask</a>
    72       </form>
     76                    <span id="expresscurate_support_message_validation" class="expresscurate_errorMessage"></span>
     77                </div>
     78                <a class="askButton send greenBackground" href="#">Ask</a>
     79            </form>
     80        </div>
    7381    </div>
    74   </div>
    7582</div>
  • expresscurate/trunk/templates/feed_dashboard.php

    r1106118 r1129694  
    4242            <div class="addFeed">
    4343                <input id="addFeed" type="text" placeholder="Feed Address" class="expresscurate_disableInputStyle"/>
    44                 <span class="expresscurate_preventTextSelection"><span></span></span>
     44                <span class="plus expresscurate_preventTextSelection"><span></span></span>
     45                <span class="expresscurate_errorMessage"></span>
    4546            </div>
    46             <span class="errorMessage"></span>
    4747            <div class="expresscurate_clear"></div>
    4848        </div>
  • expresscurate/trunk/templates/feed_list.php

    r1115335 r1129694  
    44$contentList = $feedManager->get_feed_list();
    55$sorted_feeds = array();
     6function array_sort_by_column(&$arr, $col, $dir = SORT_DESC)
     7{
     8    $sort_col = array();
     9    foreach ($arr as $key => $row) {
     10        $sort_col[$key] = $row[$col];
     11    }
     12    array_multisort($sort_col, $dir, $arr);
     13}
     14
    615if (!empty($contentList)) {
    716    foreach ($contentList as $key => $row) {
    817        if (is_array($row) && count($row) > 0) {
    918            foreach ($row as $content) {
    10                 $sorted_feeds[$content['date']] = $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);
    1129            }
    1230        }
    1331    }
    14     krsort($sorted_feeds, 2);
     32    array_sort_by_column($sorted_feeds, 'date');
    1533}
     34
     35wp_clear_scheduled_hook('expresscurate_pull_feeds');
     36$pull_feed_interval = (get_option('expresscurate_pull_hours_interval')) ? get_option('expresscurate_pull_hours_interval') : 1;
     37wp_schedule_event(strtotime("+" . $pull_feed_interval . " hour"), 'hourly', 'expresscurate_pull_feeds');
     38$nextPullTime = human_time_diff(wp_next_scheduled('expresscurate_pull_feeds'), time());
     39
    1640?>
    1741<input id="adminUrl" type="hidden" value="<?php echo get_admin_url(); ?>"/>
     
    4569                    <span class="tooltip">curate</span>
    4670                </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>-->
    4778                <li class="layout expresscurate_floatRight">
    4879                    <span class="tooltip"><?php if (get_option('expresscurate_bookmark_layout', '') == 'single') {
     
    73104                <ul class="keywords">
    74105                    <?php if (!empty($item['media']['videos'])) {
    75                         echo '<li class="media videos"><span class="tooltip">Video(s):  '.$item["media"]["videos"].'</span></li>';
     106                        echo '<li class="media videos"><span class="tooltip">Video(s):  ' . $item["media"]["videos"] . '</span></li>';
    76107                    }
    77108                    if (!empty($item['media']['images'])) {
    78                         echo '<li class="media images"><span class="tooltip">Image(s):  '.$item["media"]["images"].'</span></li>';
     109                        echo '<li class="media images"><span class="tooltip">Image(s):  ' . $item["media"]["images"] . '</span></li>';
    79110                    }
    80111                    if (!empty($item['keywords'])) { ?>
     
    99130                </ul>
    100131
    101                 <a class="postTitle" href="<?php echo $item['link'] ?>"
    102                    target="_newtab"><?php echo $item['title'] ?></a><br/>
     132                <a data-fulllink="<?php echo $item['fullLink']; ?>" class="postTitle" href="<?php echo $item['link'] ?>"
     133                   target="_blank"><?php echo $item['title'] ?></a><br/>
    103134                <a class="url" href="<?php echo $item['link'] ?>"><?php echo $item['domain'] ?></a>
    104135                <?php if (isset($item['author']) && '' != $item['author']) { ?>
     
    107138                <?php } ?>
    108139                <span
    109                     class="time"><?php echo human_time_diff(strtotime($item['date']), current_time('timestamp')) . ' ago'; ?></span></br>
     140                    class="time"><?php echo human_time_diff(current_time('timestamp'), strtotime($item['date'])) . ' ago'; ?></span></br>
    110141
    111142                <ul class="controls expresscurate_preventTextSelection">
  • expresscurate/trunk/templates/keywords.php

    r1106118 r1129694  
    6868                    <input id="addKeyword" type="text" placeholder="Add Keywords"
    6969                           class="expresscurate_disableInputStyle"/>
    70                     <span><span></span></span>
     70                    <span class="plus"><span></span></span>
    7171                    <ul class="suggestion">
    7272                    </ul>
  • expresscurate/trunk/templates/settings.php

    r1106118 r1129694  
    1515        <li class="tab-link expresscurate_preventTextSelection red" data-tab="tab-2">Smart publishing</li>
    1616        <li id="sitemapTab"
    17             class="tab-link expresscurate_preventTextSelection blue <?php if ($expresscurate_seo == 'Off') {echo 'expresscurate_displayNone';}
    18             if(get_option('expresscurate_sitemap_update_permission') == 'error') echo 'disabled';?>"
     17            class="tab-link expresscurate_preventTextSelection blue <?php if ($expresscurate_seo == 'Off') {
     18                echo 'expresscurate_displayNone';
     19            }
     20            if (get_option('expresscurate_sitemap_update_permission') == 'error') echo 'disabled'; ?>"
    1921            data-tab="tab-3">Sitemap
    2022        </li>
     
    8385                        </label>
    8486                        <input type="text" id="expresscurate_max_tags" class="controls" value="<?php
    85                         if (get_option('expresscurate_max_tags')) {
     87                        if (get_option('expresscurate_max_tags') == false) {
    8688                            echo get_option('expresscurate_max_tags');
    8789                        } else {
     
    9597                            <br/><span>&nbsp;&nbsp; The default value is 5</span></label>
    9698                        <input type="text" id="expresscurate_autosummary" class="controls" value="<?php
    97                         if (get_option('expresscurate_autosummary')) {
     99                        if (get_option('expresscurate_autosummary') == false) {
    98100                            echo get_option('expresscurate_autosummary');
    99101                        } else {
     
    188190                        <p class="title"> Keyword Statistics.
    189191                            <span class="description">
    190                                Generates comprehensive keyword statistics for the last <?php echo (get_option('expresscurate_posts_number')?get_option('expresscurate_posts_number'):100); ?>posts.
     192                               Generates comprehensive keyword statistics for the last <?php echo(get_option('expresscurate_posts_number') ? get_option('expresscurate_posts_number') : 100); ?>
     193                                posts.
    191194                            </span>
    192195                        </p>
    193196                        <input type="number" id="expresscurate_posts_number" class="controls" value="<?php
    194                                 if (get_option('expresscurate_posts_number')) {
    195                                     echo get_option('expresscurate_posts_number');
    196                                 } else {
    197                                     echo '100';
    198                                 }
    199                                 ?>" name="expresscurate_posts_number" size="4" min="100" max="300" />
     197                        if (get_option('expresscurate_posts_number')) {
     198                            echo get_option('expresscurate_posts_number');
     199                        } else {
     200                            echo '100';
     201                        }
     202                        ?>" name="expresscurate_posts_number" size="4" min="100" max="300"/>
    200203                    </li>
    201204                    <!--  -->
  • expresscurate/trunk/templates/support.php

    r1109426 r1129694  
    44$user_email = '';
    55if ($current_user->user_email) {
    6   $user_email = $current_user->user_email;
     6    $user_email = $current_user->user_email;
    77}
    88$msg_placeholder = 'Message';
    9 if(isset($_GET['type']) && $_GET['type']=='keywords'){
     9if (isset($_GET['type']) && $_GET['type'] == 'keywords') {
    1010    $msg_placeholder = 'Please, write your suggestions here ...';
    1111}
     
    1414    if ($_POST['expresscurate_support_email'] && $_POST['expresscurate_support_message']) {
    1515        $expressCurateEmail = new ExpressCurate_Email();
    16         $sent =  $expressCurateEmail->sendSupportEmail($_POST['expresscurate_support_email'], 'Plugin feedback',stripslashes($_POST['expresscurate_support_message']));
     16        $sent = $expressCurateEmail->sendSupportEmail($_POST['expresscurate_support_email'], 'Plugin feedback', stripslashes($_POST['expresscurate_support_message']));
    1717        unset($_POST);
    1818    }
     
    2424        <h2>Support</h2>
    2525    </div>
    26   <h2 class="expresscurate_displayNone"> Support</h2>
    27   <div class="">
    28     <div class="block">
    29       <label class="publicRevolution">Join the public curating revolution and leave a feedback by email or twitter</label>
     26    <h2 class="expresscurate_displayNone"> Support</h2>
    3027
    31       <div>
    32         <a href="mailto:[email protected]" class="feedbackButton redBackground">email</a>
    33         <span>or</span>
    34         <a href="https://twitter.com/CurateSupport" target="_blank" class="feedbackButton blueBackground">twitter</a>
    35       </div>
    36       <label class="margin10">Like ExpressCurate tools & want to support us?</label>
    37       <a href="https://www.bit.ly/expresscuratedonate" target="_blank"
    38          class="donate">donate</a>
     28    <div class="">
     29        <div class="block">
     30            <label class="publicRevolution">Join the public curating revolution and leave a feedback by email or
     31                twitter</label>
     32
     33            <div>
     34                <a href="mailto:[email protected]" class="feedbackButton redBackground">email</a>
     35                <span>or</span>
     36                <a href="https://twitter.com/CurateSupport" target="_blank" class="feedbackButton blueBackground">twitter</a>
     37            </div>
     38            <label class="margin10">Like ExpressCurate tools & want to support us?</label>
     39            <a href="https://www.bit.ly/expresscuratedonate" target="_blank"
     40               class="donate">donate</a>
     41        </div>
     42        <div class="block">
     43            <?php if (!$sent) { ?>
     44                <label for="expresscurate_support_email">Leave your feedback</label>
     45            <?php
     46            } else {
     47                ?>
     48                <label for="expresscurate_support_email">Thanks for your feedback</label>
     49            <?php
     50            }
     51            ?>
     52            <form method="post" action=""
     53                  id="expresscurate_support_form">
     54                <div class="errorMessageWrap">
     55                    <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle"
     56                           placeholder="Email"
     57                           value="<?php echo $user_email ?>"/>
     58                    <span id="expresscurate_support_email_validation" class="expresscurate_errorMessage"></span>
     59                </div>
     60                <div class="errorMessageWrap">
     61               <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
     62                         placeholder="<?php echo $msg_placeholder ?>"></textarea>
     63                    <span class="expresscurate_errorMessage" id="expresscurate_support_message_validation"></span>
     64                </div>
     65                <a class="feedbackButton send greenBackground" href="#">Send</a>
     66            </form>
     67        </div>
    3968    </div>
    40     <div class="block">
    41       <?php if (!$sent) { ?>
    42         <label for="expresscurate_support_email">Leave your feedback</label>
    43         <?php
    44       } else {
    45         ?>
    46         <label for="expresscurate_support_email">Thanks for your feedback</label>
    47         <?php
    48       }
    49       ?>
    50         <form method="post" action=""
    51               id="expresscurate_support_form">
    52           <input id="expresscurate_support_email" name="expresscurate_support_email" class="inputStyle" placeholder="Email"
    53                  value="<?php echo $user_email ?>"/>
    54             <label for="expresscurate_support_email" class="expresscurate_errorMessage"></label>
    55           <textarea class="inputStyle" name="expresscurate_support_message" id="expresscurate_support_message"
    56                     placeholder="<?php echo $msg_placeholder?>"></textarea>
    57             <label for="expresscurate_support_message" class="expresscurate_errorMessage"></label>
    58           <a class="feedbackButton send greenBackground" href="#">Send</a>
    59         </form>
    60     </div>
    61   </div>
    6269</div>
  • expresscurate/trunk/templates/widget.php

    r1109426 r1129694  
    8080    </div>
    8181
    82     <a href="#expresscurate_advancedSEO_widget" class="expresscurate_moveToAdvanced">Advanced SEO</a>
     82    <a href="#" class="expresscurate_moveToAdvanced">Advanced SEO</a>
    8383<?php } ?>
    8484<script type="text/html" id="tmpl-SEOControlCenter">
    8585    <div class="expresscurate_background_wrap expresscurate_preventTextSelection">
    8686        <span class="close">&#215</span>
    87         <div class="statisticsTitle expresscurate_{{data.color}}"><span>{{data.keyword}}</span></div>
     87        <div data-color="{{data.color}}" class="statisticsTitle expresscurate_{{data.color}}"><span>{{data.keyword}}</span></div>
    8888        <div class="statistics {{data.inTitle}} borderRight">
    8989            <div class="center">title</div>
Note: See TracChangeset for help on using the changeset viewer.