contentoptimizer.module in Content Optimizer 6
Same filename and directory in other branches
Analyzes node content for search engine optimization recommendations
File
contentoptimizer.moduleView source
<?php
/**
* @file
* Analyzes node content for search engine optimization recommendations
*/
/**
* Implementation of hook_menu().
*/
function contentoptimizer_menu() {
$items = array();
$items['admin/settings/contentoptimizer'] = array(
'title' => 'Content optimizer',
'description' => 'Analize and optimize node content.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'contentoptimizer_admin_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer page titles',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'contentoptimizer.admin.inc',
);
$items['contentoptimizer/analyze_js'] = array(
'title' => '',
'page callback' => 'contentoptimizer_analyze_js',
'access callback' => true,
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_form_alter().
*
* Add Content Optimizer field set to node edit forms.
*/
function contentoptimizer_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']['#value']) && $form['type']['#value'] . '_node_form' == $form_id) {
// Add the Location fields on the Node edit form
$node = $form['#node'];
$settings = variable_get('contentoptimizer_settings', array());
$form['contentoptimizer'] = contentoptimizer_form($settings, $node);
$form['#submit'][] = 'contentoptimizer_node_submit';
}
}
/**
* Get form elements for editing keyword.
*/
function contentoptimizer_form($settings, $node) {
drupal_add_css(drupal_get_path('module', 'contentoptimizer') . '/contentoptimizer.css');
$display = variable_get('contentoptimizer_display', array(
'sections',
'main',
));
drupal_add_js(array(
'contentoptimizer' => array(
'analyze_callback' => base_path() . 'contentoptimizer/analyze_js',
'nid' => $node->nid,
'display_sections' => $display['sections'] ? 1 : 0,
'display_main' => $display['main'] ? 1 : 0,
'analyze_on_start' => variable_get('contentoptimizer_analyze_on_start', '0'),
),
), 'setting');
drupal_add_js(drupal_get_path('module', 'contentoptimizer') . '/contentoptimizer.js');
$sql = '
SELECT keyword
FROM {contentoptimizer_keyword}
WHERE nid = %d
';
$keyword = db_result(db_query($sql, $node->nid));
$numforms = 1;
$form['contentoptimizer'] = array(
'#type' => 'fieldset',
'#title' => t('Content optimizer'),
'#tree' => TRUE,
'#attributes' => array(
'class' => 'contentoptimizer',
),
'#weight' => 10,
//'#weight' => $settings['form']['weight'],
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
if ($numforms == 1) {
$form['contentoptimizer']['keyword'] = array(
'#type' => 'textfield',
'#title' => t('Targeted keyword phrase'),
'#default_value' => $keyword,
);
$form['contentoptimizer']['analyze'] = array(
'#type' => 'button',
'#value' => t('Analyze Content'),
'#attributes' => array(
"onclick" => "contentoptimizer_analyze(); return (false);",
),
);
}
return $form;
}
function contentoptimizer_node_submit($form, &$form_state) {
//print "contentoptimizer_node_submit($form,$form_state)";
//print_r($form_state);
$sql = '
UPDATE {contentoptimizer_keyword}
SET keyword = "%s"
WHERE nid = %d
';
db_query($sql, $form_state['values']['contentoptimizer']['keyword'], $form_state['values']['nid']);
if (!db_affected_rows()) {
$sql = '
INSERT INTO {contentoptimizer_keyword}
(nid,keyword) VALUES
(%d,"%s")
';
db_query($sql, $form_state['values']['nid'], $form_state['values']['contentoptimizer']['keyword']);
}
}
function contentoptimizer_analyze_js() {
$ret = array();
$ret['status'] = TRUE;
$keyword = strtolower($_REQUEST['keyword']);
$node = node_load($_REQUEST['nid']);
$check_meta = true;
$ret['general']['section_label'] = t('General');
$ret['general']['recommendations'] = array();
$node->title = $_REQUEST['title'];
if ($_REQUEST['page_title'] && $_REQUEST['page_title'] != -1) {
$node->page_title = $_REQUEST['page_title'];
}
$_GET['q'] = 'node/' . $node->nid;
$title = $_REQUEST['title'];
if (module_exists('page_title')) {
$page_title_pattern = variable_get('page_title_type_' . (isset($node->type) ? $node->type : ''), '');
if (empty($page_title_pattern)) {
$page_title_pattern = variable_get('page_title_default', '[page-title] | [site-name]');
}
$page_title_pattern = str_replace('[page-title]', $_REQUEST['page_title'] && $_REQUEST['page_title'] != -1 ? $_REQUEST['page_title'] : $_REQUEST['title'], $page_title_pattern);
$page_title_pattern = str_replace('[title]', check_plain($_REQUEST['title']), $page_title_pattern);
$page_title_pattern = str_replace('[title-raw]', $_REQUEST['title'], $page_title_pattern);
$types = array();
if (isset($node)) {
$types['node'] = $node;
}
$types['page_title'] = NULL;
//Apply token patterns using token_replace_multiple
$page_title = token_replace_multiple($page_title_pattern, $types);
}
else {
$page_title = $_REQUEST['title'];
$ret['general']['recommendations'][] = t('The <a href="http://drupal.org/project/page_title" target="_blank">Page Title</a> module is not installed. We recommend installing it for enhanced control of page titles.');
}
if (!module_exists('nodewords')) {
$check_meta = false;
$ret['general']['recommendations'][] = t('The <a href="http://drupal.org/project/nodewords" target="_blank">Meta Tags / Nodewords</a> module is not installed. We recommend installing to enable editing of page meta information.');
}
$page_title0 = $page_title;
$page_title = strtolower($page_title);
$ret['page_title'] = contentoptimizer_calc_stats($page_title, $keyword);
$ret['page_title']['section_label'] = t('Page title');
$ret['page_title']['recommendations'] = array();
if ($ret['page_title']['char_count'] > 70) {
$ret['page_title']['recommendations'][] = t('Page titles should be no longer than 70 characters. Your title is currently ' . $ret['page_title']['char_count'] . ' characters. Reduce the text in your page title.');
}
else {
if ($ret['page_title']['word_count'] > 12) {
$ret['page_title']['recommendations'][] = t('Page titles should be no longer than 12 word. Your title is currently ' . $ret['page_title']['word_count'] . ' words. Reduce the number of words in your page title.');
}
else {
if ($ret['page_title']['word_count'] < 5 && $ret['page_title']['char_count'] < 40) {
$ret['page_title']['recommendations'][] = t('Page titles are the most important content area for optimization. You currently have only ' . $ret['page_title']['word_count'] . ' words. Add some descriptive keywords to your title.');
}
}
}
if ($keyword) {
if ($ret['page_title']['keyword_count'] == 0) {
$ret['page_title']['recommendations'][] = t('Your keyword phrase does not appear in the title. Add your kewyords to your title.');
}
else {
if ($ret['page_title']['keyword_count'] > 2) {
$ret['page_title']['recommendations'][] = t('Your keyword phrase appears more than 2 times in the page title. Reduce the number of times the keywords instances to less than 2.');
}
}
if ($ret['page_title']['keyword_prominence'] < 50) {
$ret['page_title']['recommendations'][] = t('Your keyword proninence is less that 50%. Increase your keyword\'s prominence by moving it closer to the begining of your page title.');
}
}
else {
$ret['page_title']['recommendations'][] = t('No keyword phrase was submitted for analysis. Input a keyword for more targeted recommendations.');
}
$ret['page_title']['msg'] .= theme_contentoptimizer_analysis_section_msg($ret['page_title'], $keyword, $page_title0);
// analize body
if (1 == 1) {
$body .= "<h2>" . $_REQUEST['title'] . "</h2>\n";
}
$body .= $_REQUEST['body'];
$body0 = $body;
$body = strtolower($body);
$body_notags = strip_tags($body);
$ret['body'] = contentoptimizer_calc_stats($body_notags, $keyword);
$ret['body']['section_label'] = t('Body: node title + node body');
$body_words_min = 200;
$body_words_max = 800;
$body_frequency_min = 2;
$body_frequency_max = 4;
$ret['body']['recommendations'] = array();
if ($ret['body']['word_count'] < $body_words_min) {
$ret['body']['recommendations'][] = t('Your body should be between %min and %max words. It is currently %words. Increase the number of words.', array(
'%min' => $body_words_min,
'%max' => $body_words_max,
'%words' => $ret['body']['word_count'],
));
}
else {
if ($ret['body']['word_count'] > $body_words_max) {
$ret['body']['recommendations'][] = t('Your body should be between %min and %max words. It is currently %words. Reduce the number of words.', array(
'%min' => $body_words_min,
'%max' => $body_words_max,
'%words' => $ret['body']['word_count'],
));
}
}
if ($keyword) {
if ($ret['body']['keyword_count'] < $body_frequency_min) {
$ret['body']['recommendations'][] = t('Your keyword phrase should occur in your body between %min and %max times. It is currently occurs only %frequency time. Increase the number of keyword occurences in your body copy.', array(
'%min' => $body_frequency_min,
'%max' => $body_frequency_max,
'%frequency' => $ret['body']['keyword_count'],
));
}
else {
if ($ret['body']['keyword_count'] > $body_frequency_max) {
$ret['body']['recommendations'][] = t('Your keyword phrase should occur in your body between %min and %max times. It is currently occurs only %frequency time. Reduce the number of keyword occurences in your body copy.', array(
'%min' => $body_frequency_min,
'%max' => $body_frequency_max,
'%frequency' => $ret['body']['keyword_count'],
));
}
}
if ($ret['body']['keyword_prominence'] < 50) {
$ret['body']['recommendations'][] = t('Your keyword proninence is less that 50%. Increase your keyword\'s prominence by moving occurences closer to the begining of your copy.');
}
}
else {
$ret['body']['recommendations'][] = t('No keyword phrase was submitted for analysis. Input a keyword for more targeted recommendations.');
}
$ret['body']['msg'] = theme_contentoptimizer_analysis_section_msg($ret['body'], $keyword, $body0);
// analize meta description
if ($check_meta && $_REQUEST['meta_description'] != -1) {
$meta_description .= strtolower(strip_tags($_REQUEST['meta_description']));
$ret['meta_description'] = contentoptimizer_calc_stats($meta_description, $keyword);
$ret['meta_description']['section_label'] = t('Meta description');
$meta_description_words_min = 10;
$meta_description_words_max = 50;
$meta_description_frequency_min = 0;
$meta_description_frequency_max = 2;
$ret['meta_description']['recommendations'] = array();
if ($ret['meta_description']['word_count'] < $meta_description_words_min) {
$ret['meta_description']['recommendations'][] = t('Your meta description should be between %min and %max words. It is currently %words. Increase the number of words.', array(
'%min' => $meta_description_words_min,
'%max' => $meta_description_words_max,
'%words' => $ret['meta_description']['word_count'],
));
}
else {
if ($ret['meta_description']['word_count'] > $meta_description_words_max) {
$ret['meta_description']['recommendations'][] = t('Your meta description should be between %min and %max words. It is currently %words. Reduce the number of words.', array(
'%min' => $meta_description_words_min,
'%max' => $meta_description_words_max,
'%words' => $ret['meta_description']['word_count'],
));
}
}
if ($keyword) {
if ($ret['meta_description']['keyword_count'] < $meta_description_frequency_min) {
$ret['meta_description']['recommendations'][] = t('Your keyword phrase should occur in your meta description between %min and %max times. It is currently occurs only %frequency time. Increase the number of keyword occurences in your meta description copy.', array(
'%min' => $meta_description_frequency_min,
'%max' => $meta_description_frequency_max,
'%frequency' => $ret['meta_description']['keyword_count'],
));
}
else {
if ($ret['meta_description']['keyword_count'] > $meta_description_frequency_max) {
$ret['meta_description']['recommendations'][] = t('Your keyword phrase should occur in your meta description between %min and %max times. It is currently occurs only %frequency time. Reduce the number of keyword occurences in your meta description copy.', array(
'%min' => $meta_description_frequency_min,
'%max' => $meta_description_frequency_max,
'%frequency' => $ret['meta_description']['keyword_count'],
));
}
}
//if($ret['meta_description']['keyword_prominence'] < 50) {
// $ret['meta_description']['recommendations'][] = t('Your keyword proninence is less that 50%. Increase your keyword\'s prominence by moving occurences closer to the begining of your copy.');
//}
}
else {
$ret['meta_description']['recommendations'][] = t('No keyword phrase was submitted for analysis. Input a keyword for more targeted recommendations.');
}
$ret['meta_description']['msg'] = theme_contentoptimizer_analysis_section_msg($ret['meta_description'], $keyword);
}
// analize meta keywords
if ($check_meta && $_REQUEST['meta_keywords'] != -1) {
$meta_keywords = strtolower($_REQUEST['meta_keywords']);
$ret['meta_keywords'] = contentoptimizer_calc_stats($meta_keywords, $keyword);
$ret['meta_keywords']['section_label'] = t('Meta keywords');
$meta_keyword_segs = explode(',', $meta_keywords);
$ret['meta_keywords']['phrase_count'] = count($meta_keyword_segs);
$meta_keywords_words_min = 5;
$meta_keywords_words_max = 50;
$meta_keywords_phrase_min = 1;
$meta_keywords_phrase_max = 15;
$meta_keywords_frequency_min = 1;
$meta_keywords_frequency_max = 2;
$ret['meta_keywords']['recommendations'] = array();
if ($ret['meta_keywords']['word_count'] < $meta_keywords_words_min) {
$ret['meta_keywords']['recommendations'][] = t('Your meta keywords should be between %min and %max words. It is currently %words. Increase the number of words.', array(
'%min' => $meta_keywords_words_min,
'%max' => $meta_keywords_words_max,
'%words' => $ret['meta_keywords']['word_count'],
));
}
else {
if ($ret['meta_keywords']['word_count'] > $meta_keywords_words_max) {
$ret['meta_keywords']['recommendations'][] = t('Your meta keywords should be between %min and %max words. It is currently %words. Reduce the number of words.', array(
'%min' => $meta_keywords_words_min,
'%max' => $meta_keywords_words_max,
'%words' => $ret['meta_keywords']['word_count'],
));
}
}
if ($ret['meta_keyphrases']['phrase_count'] < $meta_keyphrases_phrases_min) {
$ret['meta_keyphrases']['recommendations'][] = t('Your meta keywords should include %min and %max phrases. There are currently %phrases. Increase the number of phrases.', array(
'%min' => $meta_keyphrases_phrases_min,
'%max' => $meta_keyphrases_phrases_max,
'%phrases' => $ret['meta_keyphrases']['phrase_count'],
));
}
else {
if ($ret['meta_keyphrases']['phrase_count'] > $meta_keyphrases_phrases_max) {
$ret['meta_keyphrases']['recommendations'][] = t('Your meta keywords should include %min and %max phrases. There are currently %phrases. Reduce the number of phrases.', array(
'%min' => $meta_keyphrases_phrases_min,
'%max' => $meta_keyphrases_phrases_max,
'%phrases' => $ret['meta_keyphrases']['phrase_count'],
));
}
}
if ($keyword) {
if ($ret['meta_keywords']['keyword_count'] < $meta_keywords_frequency_min) {
$ret['meta_keywords']['recommendations'][] = t('Your keyword phrase should occur in your meta keywords between %min and %max times. It is currently occurs only %frequency time. Increase the number of keyword occurences in your meta keywords.', array(
'%min' => $meta_keywords_frequency_min,
'%max' => $meta_keywords_frequency_max,
'%frequency' => $ret['meta_keywords']['keyword_count'],
));
}
else {
if ($ret['meta_keywords']['keyword_count'] > $meta_keywords_frequency_max) {
$ret['meta_keywords']['recommendations'][] = t('Your keyword phrase should occur in your meta keywords between %min and %max times. It is currently occurs only %frequency time. Increase the number of keyword occurences in your meta keywords.', array(
'%min' => $meta_keywords_frequency_min,
'%max' => $meta_keywords_frequency_max,
'%frequency' => $ret['meta_keywords']['keyword_count'],
));
}
}
if ($ret['meta_keywords']['keyword_prominence'] < 30) {
$ret['meta_keywords']['recommendations'][] = t('Your keyword proninence is less that 30%. Increase your keyword\'s prominence by moving occurences closer to the begining of your copy.');
}
}
else {
$ret['meta_keywords']['recommendations'][] = t('No keyword phrase was submitted for analysis. Input a keyword for more targeted recommendations.');
}
$ret['meta_keywords']['msg'] = theme_contentoptimizer_analysis_section_msg($ret['meta_keywords'], $keyword);
}
if (module_exists('setags') && variable_get('contentoptimizer_include_setags', 0)) {
$context = $page_title . "\n" . $body;
$setags = setags_extract_tags_api($context);
$setags_msg .= "<h3>Extracted Tags</h3>";
$setags_msg .= "<ol>\n";
if (is_array($setags)) {
foreach ($setags as $key => $term) {
$setags_msg .= '<li>' . $term . "</li>\n";
}
}
else {
$setags_msg .= '<li>' . t('No terms returned') . "</li>\n";
}
$setags_msg .= "</ol>\n";
$ret['general']['msg_post_recs'] = $setags_msg;
}
$ret['general']['msg'] = theme_contentoptimizer_analysis_general_msg($ret, $keyword);
drupal_json($ret);
}
function contentoptimizer_calc_stats($content, $keyword) {
$ret = array();
$ret['char_count'] = strlen($content);
$ret['word_count'] = str_word_count($content);
if ($keyword) {
$content_segs = explode($keyword, $content);
$ret['keyword_count'] = count($content_segs) - 1;
$ret['keyword_density'] = 0;
if ($ret['word_count']) {
$ret['keyword_density'] = 100 * $ret['keyword_count'] / $ret['word_count'];
}
$ret['keyword_positionsum'] = 0;
$i = 0;
foreach ($content_segs as $seg) {
if ($i >= $ret['keyword_count']) {
break;
}
$wordpos = str_word_count($seg) + 1;
$ret['keyword_positionsum'] += $wordpos;
$i++;
}
// prominence = ($totalwords - (($positionsum - 1) / $positionsnum)) * (100 / $totalwords)
$ret['keyword_prominence'] = 0;
if ($ret['keyword_count']) {
$ret['keyword_prominence'] = ($ret['word_count'] - ($ret['keyword_positionsum'] - 1) / $ret['keyword_count']) * (100 / $ret['word_count']);
}
}
return $ret;
}
function theme_contentoptimizer_analysis_section_msg($data, $keyword, $content = '') {
$content = htmlentities($content);
if (strlen($content) > 100) {
$content = substr($content, 0, 100) . '...';
}
$msg .= '<div class="contentoptimizer_analysis">' . "\n";
$msg .= '<div class="' . ($data['recommendations'] ? "warning" : "status") . '">' . "\n";
$msg .= '<h3>' . t('Content optimizer analysis') . ($data['section_label'] ? " (" . $data['section_label'] . ")" : "") . "</h3>\n";
$msg .= '<pre>' . $content . "</pre>\n";
$msg .= t('chars') . " = " . $data['char_count'];
$msg .= ", " . t('words') . " = " . $data['word_count'];
if ($keyword) {
$msg .= ", " . t('frequency') . " = " . $data['keyword_count'];
$msg .= ", " . t('density') . " = " . number_format($data['keyword_density'], 1) . "%";
$msg .= ", " . t('prominence') . " = " . number_format($data['keyword_prominence'], 1) . "%";
}
if ($data['msg_pre_recs']) {
$msg .= "<br />\n" . $data['msg_pre_recs'];
}
if (!$data['recommendations']) {
$data['recommendations'][] = t('Optimized');
}
$msg .= "\n<ul>\n";
foreach ($data['recommendations'] as $rec) {
$msg .= "<li>{$rec}</li>\n";
}
$msg .= "</ul>\n";
if ($data['msg_post_recs']) {
$msg .= "<br />\n" . $data['msg_post_recs'];
}
$msg .= '<input class="form-submit" type="button" onclick="contentoptimizer_analyze(); return (false);" value="' . t('Analyze Content') . '"/>';
$msg .= "</div>\n";
$msg .= "</div>\n";
return $msg;
}
function theme_contentoptimizer_analysis_general_msg($data, $keyword) {
$status = "status";
if ($data['page_title']['recommendations'] || $data['body']['recommendations']) {
$status = "warning";
}
$msg .= '<div class="contentoptimizer_analysis">' . "\n";
$msg .= '<div class="' . $status . '">' . "\n";
$msg .= '<h3>' . t('Content optimizer analysis') . "</h3>\n";
if ($data['general']['msg_pre_recs']) {
$msg .= "<br />\n" . $data['general']['msg_pre_recs'];
}
foreach ($data as $section => $d) {
if (!$d['section_label']) {
continue;
}
if (!$d['recommendations']) {
if ($section == 'general') {
$d['recommendations'][] = t('OK - no general recommendations');
}
else {
$d['recommendations'][] = t('Optimized');
}
}
$msg .= "<h4>" . $d['section_label'] . "</h4>\n";
$msg .= "<ul>\n";
foreach ($d['recommendations'] as $rec) {
$msg .= "<li>{$rec}</li>\n";
}
$msg .= "</ul>\n";
}
if ($data['general']['msg_post_recs']) {
$msg .= "<br />\n" . $data['general']['msg_post_recs'];
}
$msg .= "</div>\n";
$msg .= "</div>\n";
return $msg;
}
Functions
Name![]() |
Description |
---|---|
contentoptimizer_analyze_js | |
contentoptimizer_calc_stats | |
contentoptimizer_form | Get form elements for editing keyword. |
contentoptimizer_form_alter | Implementation of hook_form_alter(). |
contentoptimizer_menu | Implementation of hook_menu(). |
contentoptimizer_node_submit | |
theme_contentoptimizer_analysis_general_msg | |
theme_contentoptimizer_analysis_section_msg |