CVS edit link for czingerline

In reference to http://drupal.org/node/757644, I am the maintainer of the Drupal Most Popular module as well as have a number of additional modules waiting to be released that I would like to contribute. I would love to get a CVS account so that I can submit this module for the public to use, and to be able to publish additional modules in the near future.

Comments

avpaderno’s picture

Hello, and thanks for applying for a CVS account.

You still need to upload the archive containing the code in a comment here.

What is your reply to what reported by sun?

lastrun.php seems to duplicate includes/lock.inc and/or cron in Drupal core?

Most of the classes in this module more or less seem to be wrappers around simple database queries. AFAIK, there are not many OOP developers active in the CVS applications review process, and this usage of OOP additionally looks a bit questionable to me (which doesn't hold off this application in any way though), so this is very likely one major cause for the delay.

czingerline’s picture

StatusFileSize
new51.38 KB

Hi.

Regarding post #21:

Objects:
I use objects to gather together common sets of functionality, which in this case are related to each of the most popular database tables. I also use them to maintain and pass around state within our application, which I have found makes the rest of the code using these objects clearer and more concise.

However, I have been careful to expose all the API functions and extension points, in mostpopular.api.php, using Drupal's functional model. The application does not expose the underlying objects directly through these functions, relying instead on passing around their IDs; nor does it require that developers writing hooks for new mostpopular services be aware of or interact directly with these objects.

lock.ini:
Drupal's locking mechanism, implemented in includes/lock.ini, provides a means for guaranteeing that only one instance of a block of code can run at a time. It is expected that the code will release the lock once it is complete or once a timeout has expired.

In contrast, the mostpopular_last_run table (and its lastrun.php wrapper class) controls how often each of the most popular cron processes are allowed to update their data from remote datasources, which is likely on the order of hours or days. They allow fine-grained control over how often to refresh the data for each interval of time, which we refer to internally as "throttles". These updates only occur as part of a cron job, of which there should only be a single instance running.

I considered using Drupal's locking for this purpose, but then the code would never release the locks and would necessarily wait instead for them to timeout on their own, which could be days. This seems like use of locks for which they were not intended. Using my own table also allows me more flexibility so I can keep track of each service and interval separately, as the number of available services and intervals are configurable.

Reviewing:
I agree that this is a complex module with many moving parts, and believe that it probably will make more sense to code reviewers if you install it and play with the configuration options. The administration pages correspond closely with the class objects.

I also recommend looking at mostpopular.api.php early in the review process, as this is where the key concepts and extension points are documented. This file is structured in a way which should be familiar to the Drupal community, even if reviewers are unfamiliar with the OOP structures.

Does this give you enough information to go on? If not, let me know and I'll post more. Thanks.

sun’s picture

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

Status: Needs review » Needs work
  • The points reported in this review are not in order or importance / relevance.
  • Most of the times I report the code that present an issue. In such cases, the same error can be present in other parts of the code; the fact I don't report the same issue more than once doesn't mean the same issue is not present in different places.
  • Not all the reported points are application blockers; some of the points I report are simple suggestions to who applies for a CVS account. For a list of what is considered a blocker for the application approval, see CVS applications review, what to expect. Keep in mind the list is still under construction, and can be changed to adapt it to what has been found out during code review, or to make the list clearer to who applies for a CVS account.
  1. License files cannot be committed in Drupal.org repository. Projects committed in Drupal.org repository have the same license used by Drupal.
  2. The version line needs to be removed from the .info file.
  3. t() is available when hook_install(), or hook_uninstall() are invoked. See the code executed from php_install() as example.
  4.   include_once(dirname(__FILE__) . '/classes/intervals.php');
    
    

    There is a Drupal function to load files containing PHP code.
    Included files should have extension .inc, not .php.

  5. Menu descriptions and titles, schema descriptions are not passed to t().
  6. Functions that are implementations of hooks should have a comment that reports that.
  7. See http://drupal.org/coding-standards to understand how a module should be written. In particular, see how the code should be formatted.
  8. "For help, look at the <a href='!basic'>basic stylesheet</a>, which turns the
    
    

    The correct placeholder for URLs is prefixed by @.

  9. The module doesn't implement hook_uninstall().

This is only a partial review.

czingerline’s picture

StatusFileSize
new51.4 KB

Hi,

I have made updates to the module. Here are responses to the items in your list:

1. License files cannot be committed in Drupal.org repository. Projects committed in Drupal.org repository have the same license used by Drupal.

**** I removed the license file from the codebase.

2. The version line needs to be removed from the .info file.

**** Done

3. t() is available when hook_install(), or hook_uninstall() are invoked. See the code executed from php_install() as example.

**** Done

4.

        include_once(dirname(__FILE__) . '/classes/intervals.php');
      

There is a Drupal function to load files containing PHP code.
Included files should have extension .inc, not .php.

**** Now using module_load_include().

5. Menu descriptions and titles, schema descriptions are not passed to t().

**** Removed t() from schema descriptions, did not find it in menu

6. Functions that are implementations of hooks should have a comment that reports that.

**** Done

7. See http://drupal.org/coding-standards to understand how a module should be written. In particular, see how the code should be formatted.

**** Can you be more specific, I believe I have been following the coding standards

8.

      "For help, look at the <a href='!basic'>basic stylesheet</a>, which turns the
      

The correct placeholder for URLs is prefixed by @.

**** Done

9. The module doesn't implement hook_uninstall().

**** It does, can you please check again?

Let me know if I can do anything else to get this module released. Thank you!

avpaderno’s picture

Status: Needs work » Fixed
  1. // $Id$
    /*
     * Drupal Most Popular - Showcase the most popular content across your Drupal website and engage your audience.
     * Copyright © 2010 New Signature
     * 
     * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
     * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     * You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
     * You can contact New Signature by electronic mail at labs@newsignature.com –or- by U.S. Postal Service at 1100 H St. NW, Suite 940, Washington, DC 20005.
     */
    module_load_include('php', 'mostpopular', 'mostpopular.api');
    

    Any reference to the license should be removed from the code.
    The copyright statement would not be anymore exact from the moment you apply patches provided by users; to make an example, Drupal core code is not stated to be copyrighted from Dries Buytaert (it is copyrighted by all the contributors).

    It usually not a good idea to unconditionally include code contained in PHP files. If the files contain form handlers, theme functions, or menu callbacks, Drupal core code allows to third-party modules to define which files must be loaded in the implementations of hook_menu(), and hook_theme(); in these cases, Drupal loads the file only when necessary.

  2.           global $is_page_authcache;
    
    

    Is the variable defined by this module?

  3.                 drupal_set_message(t('You have an invalid cookie for the most popular service'), 'error');
    
    

    Messages strings should end with a period.

  4.   public function MostPopularInterval($object) {
        $this->update($object);
      }
    
    

    PHP5 class constructor is __construct(), which is the one reported by the coding standards.

  5.   public static $table = 'mostpopular_intervals';
    
    

    If the content of the variable is not changed, why isn't the code using a class constant?

  6. The namespace respect is also valid for class names; AddThis is the name of a class that the module addthis.module would use.
  7.           include_once(drupal_get_path('module', 'mostpopular_addthis') . '/mostpopular_addthis.classes.inc');
    
    
  8.           $sql = "
                SELECT DISTINCT n.nid, n.title, c.totalcount
                FROM {node} n left join {node_counter} c on n.nid = c.nid
                WHERE n.status = 1 and n.moderate = 0 and n.created >= %d
                  AND c.totalcount >= 1 and title not like '%page not found%'
                ORDER BY c.totalcount desc, n.created desc";
    
    

    Reserved SQL keywords are written in uppercase.

  9.         '#description' => l(t('Click here to authenticate and select a Google Analytics site to monitor.'),
              'admin/settings/google-analytics-api', array(
                'query' => drupal_get_destination()
              )),
    
    

    That code is similar to the code that in the documentation of t() is reported as wrong.
    the function l() should not be used in these cases.

  10.   $form['block']['mostpopular_styling'] = array(
        '#type' => 'radios',
        '#title' => t('Stylesheet'),
        '#description' => '<p>' . t(
    "Choose how much styling to apply to the Most Popular block.
    You can add additional styling in your own theme.") . '</p>' .
          '<p>' . t(
    "For help, look at the <a href='@basic'>basic stylesheet</a>, which turns the
    service and interval links into tabs, and the <a href='@full'>full stylesheet</a>,
    which adds fonts, colors, formatting, and layouts.", array(
            '@basic' => url(drupal_get_path('module', 'mostpopular') . '/css/mostpopular-basic.css'),
            '@full' => url(drupal_get_path('module', 'mostpopular') . '/css/mostpopular-full.css'),
          )) . '</p>' .
          '<p>' . t(
    "When creating your own styles for the Most Popular block, we recommend you
    start with our full stylesheet and override it using drupal_set_css().") . '</p>',
    
        '#options' => array(
          MOSTPOPULAR_STYLE_NONE => t('No styling'),
          MOSTPOPULAR_STYLE_BASIC => t('Basic styling'),
          MOSTPOPULAR_STYLE_FULL => t('Full styling'),
        ),
        '#default_value' => variable_get('mostpopular_styling', MOSTPOPULAR_STYLE_FULL),
      );
    
    

    That code could be formatted better.
    There are other code lines that are not formatted as suggested by the coding standards (e.g., using a space before, or after the parenthesis in a function call).

  11.     '#description' => t(
    "<p>These Drupal pages will be excluded from the most popular results for any
    services that return nodes.  The homepage will automatically be excluded, but
    you can use this field to hide landing pages or other non-content pages.</p>
    <p>Each URL should be an internal Drupal path with no leading slash, and can
    point either to node/%d or to an alias.   Put each path on a separate line.</p>"),
    
    

    Avoid to include HTML tags in strings to translate; that doesn't mean to split a sentence in phrases, anyway. In this case, as the <p> tag is at the beginning of the string, it's

Thank you for your contribution! I am going to update your account.
These are some recommended readings to help with excellent maintainership:

You can find more contributors chatting on the IRC #drupal-contribute channel. So, come hang out and stay involved.
Thank you, also, for your patience with the review process.
Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

I thank all the dedicated reviewers as well.

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