CVS edit link for jasonleon

Hello,

I have built a module that fetches various statistics of a site(Such as Google pr, Alexa rank, Backlinks, Pages Indexed in different search engine and domain age). The module was developed at Drupal Code Sprint at Pune (Oct 09) and I want to publish it on drupal.org.

The Code Sprint Website: http://drupalindia2009.plug.org.in/
My module is available at http://linuxers.org/sitestats.tar.gz

If there's any issues with the code or module functionality as such, I'm ready to improve it, since this code is all about single day's work so far. I had also applied for CVS access earlier, however, due to time restrictions and studies, I couldn't follow up with the disapproval reasons. I'll be glad to have the ability to publish my module and also learn further with the experience of the same.

Thanks!

Regards,
Tushar Mahajan

Comments

chia’s picture

StatusFileSize
new80.17 KB
avpaderno’s picture

Status: Postponed (maintainer needs more info) » Needs review
Issue tags: +Module review

Remember to change status, when you upload new code.

chia’s picture

Component: Miscellaneous » Code
Category: task » feature
StatusFileSize
new75.68 KB
avpaderno’s picture

Component: Code » Miscellaneous
Category: feature » task

Please change only the status, when you upload new code.

avpaderno’s picture

Status: Needs review » Needs work

See the Drupal coding standards to understand how a module code should be written.
In particular, see the part about the namespace respect, and the use of Drupal Unicode functions (which is then valid for all the functions Drupal makes available to third-party modules).

avpaderno’s picture

Also, I think that the ereg functions are not anymore present in PHP 5.3; the code should use the preg functions.

chia’s picture

Status: Needs work » Needs review
StatusFileSize
new75.86 KB

Thanks for the update.
Yes, ereg family of functions is deprecated in PHP 5.3 and will be removed completely in PHP6. Replaced ereg function.
Please review this new code.
Thanks

chia’s picture

StatusFileSize
new75.81 KB
avpaderno’s picture

Status: Needs review » Needs work
  1.   if ($path == 'admin/help#sitestats'){
        $txt = 'This Module provide a tool that fetches various Statistics of a site such as pagerank, alexa rank, google backlinks, domain age';
        return '<p>'. t($txt) .'</p>';
      }
    

    The first argument of t() needs to be a literal string, not a variable; differently the script to extract the strings to translate will not find the string to translate.

  2.     '#type' => 'textarea',
        '#title' => t("URL ($max_url max)"),
    

    The code should use a placeholder.

  3.     '#description' => 'URLs separated by newline. Example: www.pagerankandalexa.com ',
    

    Every strings that are used in the user interface should be translatable.

  4. function sitestats_getform_submit($form,&$form_state) {
      drupal_goto('sitestats', array('urls'=> $_REQUEST['url']));
    }
    

    A submission function doesn't use drupal_goto().

  5.   require_once('func.php');
      $urls = explode("\r", $urls);
    
      $urls = array_map('trim', $urls);
      $urls = array_filter($urls, 'strlen');
      $urls = array_slice($urls, 0, variable_get('sitestats_max', 5));
    

    The statement require_once is looking for a file that is in the root directory of Drupal; the code should use module_load_include().
    Also, rather than using array_filter($urls, 'strlen'), the code could use array_filter($urls).

  6.       $params['subject'] = t(variable_get('sitestats_mail_sub', SITESTATS_MAIL_SUB));
          $params['body'] = t(variable_get('sitestats_mail_body', SITESTATS_MAIL_BODY),$vars);
    

    This error has been already reported.

  7.   $form['mail']['notified'] = array(
          '#value' => "Be notified when Pagerank on $url changes!",
          );
    

    The string is not translatable.

  8.   if ( !db_result(db_query("SELECT * FROM {sitestats} WHERE hashelement='%s'",$r['hashelement'])))
        $return = drupal_write_record('sitestats', $r);
    

    IF-statements should use the curly brachets, as reported in the coding standards.

  9.   $result['register'] = drupal_get_form('_sitestats_subscribe', $url);
      $length = variable_get('sitestats_url_length',25);
      if (drupal_strlen($url) > $length + 3) {
        $url = drupal_substr($url, 0, $length) .'...';
      }
    

    Why isn't the code using truncate_utf8()?

  10.         watchdog('sitestats', "Mail Sent to $result->mail Updated pr from $oldpr to $newpr", NULL, WATCHDOG_INFO);
    

    It would be better to use placeholders.

  11.   if (count($result) > 0) {
        drupal_set_message(t('Sitestats module Installed.'));
      }
      else {
        drupal_set_message(t('Sitestats table creation failed. Please "uninstall" the module and retry'));
      }
    

    Normally, the installation code just calls the function without to check the value returned.

  12. if( variable_get('sitestats_alexa_backlink', TRUE) ) {
      $r[] = array( 'Alexa Backlink', $rows['alexa_backlink']!=''?$rows['alexa_backlink']:'Not Available');
    }
    

    See the Drupal coding standards to understand how a module code should be written.
    The coding standars also suggest to use Drupal Unicode functions, which handle better the multi-byte strings.

  13.       '#title' => t('Email about the Change in the Pagerank'),
    

    Strings used like that should have the first word written in capital case, and the others written in lower case (with the exception of proper nouns, or acronyms).

  14.     '#description' => t('Some Template may break if URL lenght is large, to prevent it set the url length and an ellipse will be added at the end(...)'),
    

    It should be 'Some templates may break if the URL length is too big.

  15.   $form['sitestats_pr'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Google Pr?'),
        '#default_value' => variable_get('sitestats_pr', TRUE),
        );
      $form['sitestats_alexa_popularity'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Alexa Popularity?'),
        '#default_value' => variable_get('sitestats_alexa_popularity', TRUE),
        );
      $form['sitestats_alexa_backlink'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Alexa Backlink?'),
        '#default_value' => variable_get('sitestats_alexa_backlink', TRUE),
        );
      $form['sitestats_yahoo_backlink'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Yahoo Backlink?'),
        '#default_value' => variable_get('sitestats_yahoo_backlink', TRUE),
        );
      $form['sitestats_google_backlink'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Google Backlink?'),
        '#default_value' => variable_get('sitestats_google_backlink', TRUE),
        );
      $form['sitestats_technorati_rank'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Technorati Rank?'),
        '#default_value' => variable_get('sitestats_technorati_rank', TRUE),
        );
        $form['sitestats_google_indexed'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Google Indexed?'),
        '#default_value' => variable_get('sitestats_google_indexed', TRUE),
        );
      $form['sitestats_alltheweb'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Alltheweb Result?'),
        '#default_value' => variable_get('sitestats_alltheweb', TRUE),
        );
      $form['sitestats_yahoo_listed'] = array(
        '#type' => 'checkbox',
        '#title' => t('Listed In Yahoo Directory?'),
        '#default_value' => variable_get('sitestats_yahoo_listed', TRUE),
        );
      $form['sitestats_dmoz_listed'] = array(
        '#type' => 'checkbox',
        '#title' => t('Listed In DMOZ.org'),
        '#default_value' => variable_get('sitestats_dmoz_listed', TRUE),
        );
      $form['sitestats_domain_age'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show Domain Age?'),
        '#default_value' => variable_get('sitestats_domain_age', TRUE),
        );
    

    It would be better to use the form field checkboxes.

  16. //get alexa backlink
    function _sitestats_alexa_backlink($url) {
    	global $alexa_backlink;
    	if ($alexa_backlink!=0)
    	{
    		return $alexa_backlink;
    	} else {
    		$rank = _sitestats_get_alexa_popularity($url);
    		return $alexa_backlink;
    	}
    }
    
    //get alexa reach rank
    function _sitestats_alexa_reach_rank($url) {
    	global $alexa_reach;
    	if ($alexa_reach!=0)
    	{
    		return $alexa_reach;
    	} else {
    		$rank = _sitestats_get_alexa_popularity($url);
    		return $alexa_reach;
    	}
    }
    

    The code is not formatted as the coding standards suggest.

chia’s picture

Status: Needs work » Needs review
StatusFileSize
new75.54 KB

Thanks KiamLaLuno for reviewing the module. I have made those changes, please review this new code.

chia’s picture

StatusFileSize
new75.13 KB

removed sitestats.admin.inc and added that code to sitestats.module, because of single function in that file.

chia’s picture

StatusFileSize
new75.12 KB

Fixed couple of more coding Standards Issues

chia’s picture

StatusFileSize
new75.12 KB

Fixed couple of more coding Standards Issues

avpaderno’s picture

Status: Needs review » Needs work

See the Drupal coding standards to understand how a module code should be written.

avpaderno’s picture

What is wrong with the following code?

  if($pos === false){} else{
    $pagerank = (int) substr($data, $pos + 9);
    return $pagerank;
  }
chia’s picture

Status: Needs work » Needs review
StatusFileSize
new73.87 KB

Thanks KiamLaLuno for the update.
I have fixed those coding standard issues.

avpaderno’s picture

Status: Needs review » Needs work
  1.       $params['subject'] = t(variable_get('sitestats_mail_sub', SITESTATS_MAIL_SUB));
          $params['body'] = t(variable_get('sitestats_mail_body', SITESTATS_MAIL_BODY), $vars);
    

    The first argument of t() is a literal string, not a dynamic value; differently, the script to extract the strings to translate will not extract the string.

  2.   if ( !db_result(db_query("SELECT * FROM {sitestats} WHERE hashelement='%s'",$r['hashelement']))) {
        $return = drupal_write_record('sitestats', $r);
      }
    

    db_result() is used when the query is selecting a single field of the table, not the full row; the code should use a different function.

  3.     '#type' => 'textarea',
        '#title' => t("URL (%max max)", array('%max' => $max_url)),
    

    The title should say URLs (%max max); differently, users will probably understand that that is the length of the URL, not the maximum number of URLs they can insert.
    Are you sure that the placeholder %max is the one you want to use?

  4.   $urls = array_map('trim', $urls);
      $urls = array_filter($urls, 'strlen');
    

    The coding standards also report to use Drupal Unicode functions; although, in this case it's enough to write array_filter($urls).

  5.     $msg = $r['mail'].' is now registered to the pagerank update on '.$r['url'];
    

    Concatenating string to obtain a string that is then passed to t() is normally not a good idea (watchdog() passes the string to t()); $r['mail'], and $r['url'] needs to be sanitized, before to be output (t() does that, if it gets the right placeholders).

  6. function sitestats_getstats($url) {
      $url = str_replace('www.','',$url);
      $url = str_replace('http://','',$url);
      $url = str_replace('https://','',$url);
    

    str_replace() accepts arrays as parameters; there isn't the need to call the function three times.

  7.   $options = array(
          'PR' => "Show Google Pr?", 
          'AP' => "Show Alexa Popularity?", 
          'AB' => "Show Alexa Backlink?", 
          'GB' => 'Show Google Backlink', 
          'TR' => 'Show Technorati Rank?', 
          'GI' => 'Show Google Indexed?', 
          'AI' => 'Show Alltheweb Indexed?', 
          'DM' => 'Listed in DMOZ.org', 
          'DA' => 'Show Domain Age'
          );
    

    Every strings used in the user interface should be translated.
    In the options for the checkbox(ex) form field, the question mark is never used at the end of the string.
    Strings used in user interface should have the first word in capital case, and the other words in lower case (with the exception of proper nouns, adjectives derived from proper nouns, and acronyms).

  8.       '#multicolumn' => array('width' => 3, 'row-major' => TRUE),
    

    That option is not used by Drupal core code; is it used by a third-party module?

  9. // Run the javascript on page load.
    if (Drupal.jsEnabled) {
      $(document).ready(function () {
        $("input[@name=submit]").click(sitestats_handler);
        $('<div id="loading1"></div>').insertBefore('#target_sitestats').hide();
      }); 
    }
    

    Why isn't the code using Drupal behaviors?

avpaderno’s picture

Title: jasonleon [jasonleon] » chia [jasonleon]
chia’s picture

StatusFileSize
new73.83 KB

Thanks KiamLaLuno once again for the update.

            $params['subject'] = variable_get('sitestats_mail_sub', SITESTATS_MAIL_SUB);
            $params['body'] = strtr(variable_get('sitestats_mail_body', SITESTATS_MAIL_BODY), $vars);
      

Removed t() function

2.
3.

        if ( !db_result(db_query("SELECT hashelement FROM {sitestats} WHERE hashelement='%s'", $r['hashelement']))) {
          $return = drupal_write_record('sitestats', $r);
        }
      

used single column hashelement instead of entire row

4.

          '#type' => 'textarea',
          '#title' => t("URLs (@max_url max)", array('@max_url' => $max_url)),
      

changed the name of the placeholder from %max to @max_url

5.

        $urls = array_map('trim', $urls);
        $urls = array_filter($urls, 'strlen');
      

changed to $urls = array_filter($urls);

6.

          $msg = $r['mail'].' is now registered to the pagerank update on '.$r['url'];
      

Concatenating string to obtain a string that is then passed to t() is normally not a good idea (watchdog() passes the string to t()); $r['mail'], and $r['url'] needs to be sanitized, before to be output (t() does that, if it gets the right placeholders).

$msg = '!mail is now registered to the pagerank update on !url';
$vars = array('!mail' => $r['mail'], '!url' => $r['url']);
watchdog('sitestats', $msg, $vars, WATCHDOG_INFO);
echo t($msg, $vars);
}

7.

      function sitestats_getstats($url) {
        $url = str_replace('www.','',$url);
        $url = str_replace('http://','',$url);
        $url = str_replace('https://','',$url);
      

Thanks for pointing it out changed to
$url = str_replace(array('www.', 'http://', 'https://'), '', $url);

8.

         $options = array(
      'PR' => t("Show google pr"), 
      'AP' => t("Show alexa Popularity"), 
      'GB' => t("Show google backlink"), 
      'GI' => t("Show google indexed"), 
      'AI' => t("Show alltheweb indexed"), 
      'DM' => t("Listed in DMOZ.org"), 
      'DA' => t("Show domain age")
      );  

      

Every strings used in the user interface should be translated.
In the options for the checkbox(ex) form field, the question mark is never used at the end of the string.
Strings used in user interface should have the first word in capital case, and the other words in lower case (with the exception of proper nouns, adjectives derived from proper nouns, and acronyms).

Done!

9.

            '#multicolumn' => array('width' => 3, 'row-major' => TRUE),
      

That option is not used by Drupal core code; is it used by a third-party module?
One of the module uses this code

http://drupal.org/project/multicolumncheckboxesradios
I have commented this line since i dont have this as a dependency for my module.

10.

      // Run the javascript on page load.
      if (Drupal.jsEnabled) {
        $(document).ready(function () {
          $("input[@name=submit]").click(sitestats_handler);
          $('<div id="loading1"></div>').insertBefore('#target_sitestats').hide();
        });
      }
      

Changed to

Drupal.behaviors.sitestats = function () {
$("input[@name=submit]").click(sitestats_handler);
$('#loading1').hide();
};

chia’s picture

Status: Needs work » Needs review
avpaderno’s picture

Status: Needs review » Needs work

The code is using some PHP functions when there are equivalent Drupal functions, which should be preferred.

chia’s picture

Status: Needs review » Needs work
StatusFileSize
new73.61 KB

Thanks again kiamlaluno for the reply
I have replaced curl functions which drupal_http_request, i could find this, but not sure if there are any other out there :).

chia’s picture

Status: Needs work » Needs review

forgot to change the status

avpaderno’s picture

Status: Needs work » Needs review

urlencode() should be replaced by drupal_urlencode(), which fixes some Apache problems.

avpaderno’s picture

Status: Needs review » Fixed
chia’s picture

Thanks a lot Kiamlaluno.
I will make that change and again thanks for all your time

Status: Fixed » Closed (fixed)
Issue tags: -Module review

Automatically closed -- issue fixed for 2 weeks with no activity.

avpaderno’s picture

Component: Miscellaneous » new project application
Assigned: Unassigned » avpaderno
Issue summary: View changes
Status: Closed (fixed) » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.