Abstract

Drupal sites are subject to web-bot registrations that target Drupal's /user/register url.

The Members Page module was crafted to fight this nuisance by creating a dedicated members page and registration page. The latter is available even if /user/register access is blocked. For added security, both page locations (url's) can be changed. Web-bots simply don't know where to look.

The Members page

The Members page has a two panel content block with three different viewing modes:

  1. for the anonymous visitor
  2. for the member -- a user who has logged in by way of a session cookie or by providing a valid username and password
  3. for admins or members who have edit permissions

The visitor view has a greeting, a login block for existing members, and a link to a special registration form for new members. This registration form has elevated privileges. A visitor who completes this form will be registered immediately without admin approval (but still subject to email verification) regardless of the current site settings.

The members view has a greeting and a personalized configurable user-menu block.

Both greetings can be edited -- a good place to encourage sign-up of new members or to publish news items or new links for your current members.

Downloads, documentation, and support: http://sontag.ca/drupal/members-page-module

Available for Versions 6, 7 & 8.

Introduced here: http://groups.drupal.org/node/166004

Project page here: http://drupal.org/sandbox/Diogenes/1234042
Git repository here: http://drupal.org/project/1234042/git-instructions

Please ignore the links below - they are out of date and I can't delete them.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Diogenes’s picture

Category: support » feature
berkas1’s picture

Category: feature » task
klausi’s picture

Status: Needs review » Needs work

* remove all old CVS $Id tags, they are not needed anymore
* provide a README.txt
* info file: "php = 5.2" this is not needed, as drupal 7 core itself requires PHP 5.2
* why do you need hook_init()? just to populate a global variable? why not doing it when needed?
* real_user_register_access(): every function name needs to start with your module name to avoid name clashes.
* real_user_register_access(): the function body deserves its own line.
* hook_uninstall() does not belong in the module file
* jimLog(): obviously a debugging function, please remove it from the repository. Use the devel module for development: http://drupal.org/project/devel
* Check all docblocks of your function to match http://drupal.org/node/1354#functions

Diogenes’s picture

klausi,

Thank you so much for the excellent code review. I see you have been a busy man.

I was waiting, and hope was fading. But step away from the keyboard for a few weeks, and look what's there when you return!

Once again, thank-you. Now that I see how it's done, perhaps I can pitch in and help like you. Success with your thesis, spirit, and career.

-Dio

P.S. -will update Notbot shortly

Diogenes’s picture

Status: Needs work » Needs review

Cleaned up code per klausi's recommendations.

Added support for the popular Logintoboggan and Content Profile modules in the latest 6.x-1.x commit.

klausi’s picture

Status: Needs review » Needs work

There are still files other than README.txt in the master branch, make sure to remove them. See also step 5 in http://drupal.org/node/1127732
Review of the 7.x-1.x branch:

  • Run coder to check your style, some issues were found (please check the Drupal coding standards):
    Severity minor, Drupal Commenting Standards, Internationalization, Drupal Security Checks, Drupal SQL Standards, Drupal Coding Standards
    
    sites/all/modules/pareview_temp/test_candidate/notbot.install:
     +8: [minor] Format should be * Implements hook_foo().
     +13: [normal] The $text argument to l() should be enclosed within st() so that it is translatable from within the install.
     +13: [normal] Use st() instead of t() in hook_install(), hook_uninstall() and hook_update_N()
     +13: [normal] The $message argument to watchdog() should NOT be enclosed within t(), so that it can be properly translated at display time.
     +14: [normal] Use st() instead of t() in hook_install(), hook_uninstall() and hook_update_N()
     +14: [normal] The $string argument to t() should not begin or end with a space.
    
    Status Messages:
     Coder found 1 projects, 2 files, 5 normal warnings, 1 minor warnings, 0 warnings were flagged to be ignored
    
  • Drupal Code Sniffer has found some code style issues (please check the Drupal coding standards):
    
    FILE: ...pace/drupal-7/sites/all/modules/pareview_temp/test_candidate/README.txt
    --------------------------------------------------------------------------------
    FOUND 1 ERROR(S) AND 1 WARNING(S) AFFECTING 2 LINE(S)
    --------------------------------------------------------------------------------
      55 | WARNING | Line exceeds 80 characters; contains 81 characters
     124 | ERROR   | Files must end in a single new line character
    --------------------------------------------------------------------------------
    
    
    FILE: ...ace/drupal-7/sites/all/modules/pareview_temp/test_candidate/notbot.info
    --------------------------------------------------------------------------------
    FOUND 1 ERROR(S) AFFECTING 1 LINE(S)
    --------------------------------------------------------------------------------
     4 | ERROR | Files must end in a single new line character
    --------------------------------------------------------------------------------
    
    
    FILE: .../drupal-7/sites/all/modules/pareview_temp/test_candidate/notbot.install
    --------------------------------------------------------------------------------
    FOUND 12 ERROR(S) AFFECTING 10 LINE(S)
    --------------------------------------------------------------------------------
      6 | ERROR | Whitespace found at end of line
      8 | ERROR | Expected 1 space(s) before asterisk; 0 found
      9 | ERROR | Expected 1 space(s) before asterisk; 0 found
     11 | ERROR | Expected "if (...) {\n"; found "if(...) {\n"
     11 | ERROR | Expected 0 spaces before closing bracket; 1 found
     12 | ERROR | Inline comments must start with a capital letter
     12 | ERROR | Inline comments must end in  full-stops, exclamation marks, or
        |       | question marks
     14 | ERROR | Concat operator must be surrounded by spaces
     16 | ERROR | Whitespace found at end of line
     17 | ERROR | Whitespace found at end of line
     18 | ERROR | Whitespace found at end of line
     23 | ERROR | Whitespace found at end of line
    --------------------------------------------------------------------------------
    
    
    FILE: ...e/drupal-7/sites/all/modules/pareview_temp/test_candidate/notbot.module
    --------------------------------------------------------------------------------
    FOUND 50 ERROR(S) AND 1 WARNING(S) AFFECTING 37 LINE(S)
    --------------------------------------------------------------------------------
       4 | ERROR   | Trailing punctuation for @see references is not allowed.
       4 | ERROR   | Trailing punctuation for @see references is not allowed.
       5 | ERROR   | Whitespace found at end of line
       7 | ERROR   | Whitespace found at end of line
     146 | ERROR   | Whitespace found at end of line
     155 | ERROR   | Whitespace found at end of line
     162 | ERROR   | Whitespace found at end of line
     163 | ERROR   | Whitespace found at end of line
     171 | ERROR   | Inline comments must start with a capital letter
     171 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     171 | ERROR   | Whitespace found at end of line
     173 | WARNING | Line exceeds 80 characters; contains 99 characters
     173 | ERROR   | Inline comments must start with a capital letter
     173 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     173 | ERROR   | There must be no blank line following an inline comment
     173 | ERROR   | Comments may not appear after statements.
     174 | ERROR   | Whitespace found at end of line
     175 | ERROR   | Inline comments must start with a capital letter
     175 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     178 | ERROR   | Inline comments must start with a capital letter
     178 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     178 | ERROR   | There must be no blank line following an inline comment
     180 | ERROR   | Expected "if (...) {\n"; found "if(...) {\n"
     181 | ERROR   | Concat operator must be surrounded by spaces
     185 | ERROR   | Expected "if (...) {\n"; found "if(...) {\n"
     186 | ERROR   | Concat operator must be surrounded by spaces
     189 | ERROR   | Whitespace found at end of line
     190 | ERROR   | Comments may not appear after statements.
     190 | ERROR   | Inline comments must start with a capital letter
     191 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     191 | ERROR   | Comments may not appear after statements.
     210 | ERROR   | Whitespace found at end of line
     222 | ERROR   | Whitespace found at end of line
     232 | ERROR   | Inline comments must start with a capital letter
     232 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     244 | ERROR   | Whitespace found at end of line
     245 | ERROR   | Inline comments must start with a capital letter
     245 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     253 | ERROR   | Whitespace found at end of line
     257 | ERROR   | Whitespace found at end of line
     258 | ERROR   | Whitespace found at end of line
     261 | ERROR   | Whitespace found at end of line
     262 | ERROR   | Whitespace found at end of line
     265 | ERROR   | Whitespace found at end of line
     266 | ERROR   | Inline comments must end in  full-stops, exclamation marks, or
         |         | question marks
     276 | ERROR   | Whitespace found at end of line
     279 | ERROR   | Whitespace found at end of line
     291 | ERROR   | Whitespace found at end of line
     299 | ERROR   | Whitespace found at end of line
     302 | ERROR   | Whitespace found at end of line
     303 | ERROR   | Files must end in a single new line character
    --------------------------------------------------------------------------------
    

This automated report was generated with PAReview.sh, your friendly project application review script. Go and review some other project applications, so we can get back to yours sooner.

patrickd’s picture

You can use http://ventral.org/pareview to resolve these issues, if you got any questions on that, please ask!

After you fixed the coder issues in the .install file I'd suggest you to switch back to 'needs review' so your application is not blocked due to coding standart violations.

Diogenes’s picture

Status: Needs work » Needs review

OK - cleaned up per code sniffer, added 8.x-1.x-dev branch, cleaned out master.

Try again?

patrickd’s picture

You can name the branches however you want, but if you want them to be recognized by drupal.org as releases you have to be shure that they are well formatted, eg: 7.x-1.x, 8.x-2.x.. More information here: http://drupal.org/node/1015226

Diogenes’s picture

If I may quote a famous American cultural icon…

DOH!

I was making an assumption based on what I was downloading. (note to self - Self: RTFM).

On the other hand - I am getting quite comfortable with git.

OK - back at ya. - SERVE!

And why is there no emoticon widget when you need one?

klausi’s picture

Status: Needs review » Needs work
FileSize
1.65 KB

Review of the 7.x-1.x branch:

This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. Go and review some other project applications, so we can get back to yours sooner.

manual review:

  • notbot_preprocess_block(): style information should be done in CSS files only.
  • "require_once drupal_get_path('module', 'logintoboggan') . '/logintoboggan.module';": no need to include the module file, if a module is enabled the module file is always loaded automatically by drupal core. Same for profile2.module.
  • "$form = user_register_form($form, $form_state);": you should not call that function directly, use drupal_get_form() and any form_alter() will be applied also.
  • notbot_settings_validate(): use menu_get_item() to check if a path exists.
  • notbot_block_role(): why is this function needed? Shouldn't this be done on install?
Diogenes’s picture

Title: NotBot module - project application » Members Page module - project application
Status: Needs work » Needs review

Thanks for the review Klausi, you have a good eye for code. You actually read the code, understood it, and made intelligent comments. A rare gift (or maybe curse). You could be a religious scholar. Maybe you are. I digress.

There have been a lot of revs and commits since your last review. A summary:

The project name has been re-branded to "Members Page" (from NotBot) and the module installs as "members" rather than "notbot".

Now a point-by-point of your review:

  1. style information should be done in CSS files only. - This is a dedicated page that renders 2 different views - one with a login-block, the other with a user-menu. Typically both blocks are rendered within a sidebar. The members module renders both blocks by code, on a dedicated page, regardless of the current site settings. A 30% width for the drupal blocks works with almost all themes in this context.
  2. require_once - I saw this comment and immediately thought "why is this code in there?" My only defense is that I did this after adding the module and failing to enable it. Stupid. Then I copied the code! Stupider! I promise not to do it again.
  3. you should not call that function directly, use drupal_get_form() and any form_alter() will be applied also

    I read this and I thought "yeah, he's right". So then I tried it. It looked liked it worked so I checked it it. It didn't work (discovered upon testing).

    Submitting the form rendered with drupal_get_form() resulted in validation errors - none of the fields completed were valid and the page submit returned with a totally blank form. I tried to debug this but was overwhelmed by the drupal_render array that was returned.

    You are right Klausi, in that drupal_get_form() should be used. But this module was developed from the bottom-up rather than from the top-down. I can't figure out why this does not work (yet) but I ask that you make an exception here.

  4. use menu_get_item() - done - thanks for the tip..
  5. notbot_block_role() - gone - no longer needed with new design.
drupaledmonk’s picture

Status: Needs review » Needs work

Please review the code using http://ventral.org/pareview

FILE: ...-pareview/sites/all/modules/pareview_temp/test_candidate/members.module
--------------------------------------------------------------------------------
FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
319 | ERROR | Missing parameter type at position 1
321 | ERROR | Missing parameter type at position 2
323 | ERROR | Missing parameter type at position 3
--------------------------------------------------------------------------------
patrickd’s picture

Status: Needs work » Needs review

please don't block deeper reviews because of little formatting errors ;-)

drupaledmonk’s picture

sorry about that, reviewed and tested the 6.x branch, works fine!!

Diogenes’s picture

/**
 * Renders a drupal block without using block_page_build().
 *
 * @param $fields
 *   Associative array of block fields required to render the block.
 * @param $child_render_func
 *   A callback that returns #children - an HTML string.
 * @param $subject
 *   A string for the block title.
 *
 * @returns $block
 *   A block for rendering by theme('block', $block);
 * @see members_page()
 */
function members_render_block($fields, $child_render_func, $subject) {

Could someone explain why the errors reported above are being flagged? I honestly don't know what I'm doing wrong. I copied the format used in blocks.module (been looking at that file a lot lately).

I suppose I should RTFM on Doxygen again but ... zzzzz.

patrickd’s picture

http://drupal.org/node/1354#functions

Scroll a little down to "Data types on param/return" and have a look at the changes introduced by d8.

Diogenes’s picture

Ah - I see - thank-you patrickd!

Diogenes’s picture

Issue summary: View changes

Added new versions and contrib mod info.

Diogenes’s picture

Title: Members Page module - project application » Members Page

Revised the Issue title

Now fully operational for versions 6, 7 and 8.

D7 version does not appear to work with the Fusion Accelerator module.

chrisroane’s picture

MANUAL REVIEW FOR 7.x-1.x
-------------------------

1. A fairly minor issue, but it would be worth mentioning in your installation instructions that they will need to clear the drupal cache in order for the new url's to work on the site. It also may be worth mentioning this on the config page (letting them know that if they change the path, the cache should be cleared).

2. Is there a reason why they admin area for modifying the message for members/non members is not in a separate configuration area? I didn't see an explanation for this in the readme or installation instructions.

It might be more straightforward to put all of the configuration setttings into one area that you can then define in the .info file. That way it is very obvious where everything is for this module.

3. This isn't totally necessary, but it would make the .module file more simple if you moved the admin functions to a separate file. I don't think this is a requirement...just a suggestion. :)

4. members.inc: members_check_url_free()....I understand what you are doing with the code to validate the path. However, why couldn't you use drupal_lookup_path() to accomplish the same thing? You could run the function twice to see if there is a source path or alias with that value already being used.

I went through the code and the items listed above are the only things that came to mind. However, since these are not major things, I'm keeping it set to needs review.

AUTO REVIEW for 7.x-1.x
-----------
- No errors via the Coder module.

- Ran the online PAReview tool. There are a few minor errors that came up, that should be easy to fix: http://ventral.org/pareview/httpgitdrupalorgsandboxdiogenes1234042git-7x-1x

patrickd’s picture

Status: Needs review » Needs work

note that your modules short-name is already reserved but abandoned (http://drupal.org/project/members).
Have a look at how to deal with abandoned projects and how to take it over.

please don't use variables in camelcase-format like arrayObject use array_object instead

I was not able to enable your module

patrickd@patrickd-netbook:~/www/drupal-7-test/sites/all/modules$ drush en members -y
The following extensions will be enabled: members
Do you really want to continue? (y/n): y
<pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>Couldn't resolve host 'http'</pre><pre>[...]

because your doing kind of crazy stuff on install

// Check for existing 'register/user' url, if it exists then try a different name
  $register_url = 'register/user'; $count = 1;
  while (TRUE) {
    $path = '/' . $register_url;
    drupal_set_message(st("checking for @path", array('@path' => $path)));
    if (members_check_url_free($register_url)) {
      break;
    }
    $register_url = 'register/user' . ++$count;
  }

have a look at drupal_valid_path() maybe this solves your needs.
Anyway you should not check url's your way because of performance and server load.

Please do some more exhaustive testing before pushing your code, otherwise we're not able to test it in-depht.

Diogenes’s picture

FileSize
66.84 KB
50.26 KB

Thanks for the review and comments chrisroane.

1) Are you sure the cache needs to be cleared? I think installing a module does all the necessary work up front. As for changing the URL's after install, the submit function does a menu_rebuild(). I was hoping that might be enough. Anyways, clearing the cache is one of the first things I learned about installing modules. I figure if you have Drupal up and running, you already know about that.

2) I'm not clear on what you mean here. The message (or greetings) both appear on the same page, the difference being whether the user is logged-in or not. Maybe best explained with a picture. If you are an Admin (or whatever) you can edit both greetings on the Members Page itself.

3) You would not believe some of the dumb variable names I think up at first, so I do a lot of global search and replace (with verify). I even did a module name change from NotBot to Members Page (read the first sentence again to really understand me). It's really nice if it's all in one file. Hey - it's only 600 lines ;-)

4) Oh man, I just knew that would come up! OK - I have tried drupal_lookup_path(), drupal_http_request() and menu_get_item(). drupal_http_request() worked the best for D6 but failed in spectacular fashion for D7 & D8 in a real test scenario (where the default urls are taken). I have sought advice from the experts and even tested their suggestions until I was ready to scream. On the other hand the code and my expertise in drupal keeps getting better and better. I digress.

I wrote members_check_url_free() using the php curl library because it is simple, widely used, well documented and pure php. It does not rely on any Drupal code. And it works across 3 versions of Drupal. It is 13 lines long. Compare this with any of the above functions.

BTW - the members.inc file has one function used in both the .module and .install file. I had to use an include_once directive in D7 but D8 was happy with a simple include. Curious.

Once again, thanks for the comments. I really do need to add a picture to the project page. This is a shot of the dev system. I am having some fun testing. Don't worry, it won't be in the release code.

Diogenes’s picture

OK patrickd - I'm in a bit of a conundrum. I develop on a Win 7 machine. It has dual boot with Ubantu but I'm not quite there yet with Drush and all.

I have no idea how to replicate or debug what you have done. Can I ask you to try a conventional install rather than with Drush?

The crazy stuff you refer to simply increments the url (members, members2, members3, etc) until an available url (not already used) is found. That's all. I don't think it's near as crazy as the code in drupal_http_request(), menu_get_item() or even drupal_valid_path().

I have tested this in many different ways and with D6, D7, and D8 and with over 20 different themes on a Windows system and on a Linux shared host.

I keep being told I am not doing things the Drupal way. Know what? Sometimes the Drupal way doesn't work. I keep discovering this with modules that I try to get working in D7.

Sorry for the rant, but this gets the project pushed to the back of the queue and I can tell you now there is precious little I plan to change. I'm approaching 90 commits now and it has been tested pretty exhaustively, just not with drush.

Diogenes’s picture

Status: Needs work » Needs review
FileSize
20.71 KB
19.54 KB

@patrickd

I have replaced the reference of $_SERVER['SERVER_NAME'] with the Drupal global $base_url in both the D7 and D8 versions and have tested both in my test environment: WAMP stack - virgin database install with a Basic page and an Article already occupying the module default urls of 'members' and 'register/user' respectively.

Attached are screen shots of each install, with diagnostic messages that indicate that a successful install did happen.

Replacing a PHP global with a Drupal global may not be the best answer here (IMHO), but I believe it may remedy the problem you had with the drush install.

chrisroane’s picture

Diogenes:

1. What may be common sense to you and people who have worked a lot with modules, may not be so obvious to everyone. For the module to work on my local machine, I had to clear cache after I installed the module. This is not the end of the world, but you may encounter people experiencing the same issue.

2. I know where to modify both pages. But after I enabled the module, it wasn't exactly clear where to go to access these. At a minimum, I would specify this in the readme file.

4. This relates to what patrickd brought up. The issue here is the way you are testing to see a valid url requires internet connectivity by the server. If you are working with the module on a local machine, the site may not have this access and this assumption cannot be made.

I was able to get the module enabled on my local machine, however I just noticed that there were a lot of messages trying to look for a valid url.

I'm going through the same process in getting a project approved, and I understand your frustration. Just keep in mind that you are applying to get access to create full projects, and it goes beyond more than simply your project. Sometimes following coding standards is not the most fun process, but it does increase the quality and consistency of the code from the community as a whole.

I understand you are trying to push all three versions of your module at once. Why not just focus on the Drupal 7 version and drop the other versions until you can get that release ready and then move onto the other versions? Just a though. :)

Diogenes’s picture

Thanks chrisroane;

1. OK - I'll add the "flush cache recommendation". I've never had the need to do this myself (just tested again on a live site) but I'll take your word for it.

2. Were you speaking of the location of the admin fields where you change the url's? They are located on this form (admin/config/people/accounts) because the behavior of the registration form is set by other existing fields on the same page (the registration/cancellation field set).

The module has a detailed help page that has links to the configuration pages for the module. I copied this same text to the readme file but the help text is always changing. I look into making it a bit clearer.

Or perhaps you did not know where the members page was? That's not immediately obvious. I could probably explain this better. Have a look at the help page. There are links on it that open a new tab but the links have no underscore so they don't really jump out. Any suggestions on improving the text would be appreciated. I really struggle with this kind of stuff.

4. ?? I'm not sure I follow your logic about connectivity. The code is testing to see if a url exists before it claims it as it's own. In other words, it's looking for an invalid url.

function members_check_url_free($url) {
  global $base_url;

  $url = $base_url . '/' . $url;
  $cptr = curl_init();
  curl_setopt($cptr, CURLOPT_URL, $url);     // set url
  curl_setopt($cptr, CURLOPT_NOBODY, TRUE);  // no body, just header
  curl_setopt($cptr, CURLOPT_CONNECTTIMEOUT, 2);
  $content = curl_exec($cptr);
  $info = curl_getinfo($cptr);
  $errs = curl_error($cptr);
  if (!empty($errs)) {
    echo "<pre>"; print_r($errs); echo "</pre>";
  }
  curl_close($cptr);
  return $info['http_code'] == '404' ? TRUE : FALSE;
}

This is simply a page request (headers only, no body, 2 sec timeout) for a url. If the url does not exist, then a '404' is and converted to a TRUE. This function is fast, simple, and efficient. Considerations of function overhead and performance don't really matter for an install and the Member Page urls will not be changed often in a real situation, maybe not at all.

You can have a url on a Drupal website that Drupal is completely unaware of (I have several of those on my own website). Those url's are off limits for the Members Page module and Drupal doesn't even know about them. It does not make sense to use Drupal functions to detect this conflict because they may not work. Let me be more blunt - in some cases they simply DO NOT WORK as one might expect.

The function I wrote originally had no drupal dependencies. Now it has one ($base_rurl) but I only added that in there because I thought it might fix the drush enable command that patrickd had trouble with. All those messages you saw were just diagnostic messages I added to verify what I expected. They will largely disappear.

Regarding my simultaneous D6-8 dev effort, I currently have a D6 and a D7 live site that have these modules installed. Since I have a multi-site, multi version development platform, testing a D8 install is not a big deal once you have figured out a decent test sequence. And Git fetch makes updates so easy.

Let me sum it up this way. I have a simple function (13 lines) that works (for me) across 3 major versions of Drupal and has no Drupal dependencies. It will detect a url on a Drupal site that is not registered in any way with the Drupal system.

Having a module dynamically set a url is a bit of a novel idea for Drupal. I don't know if it's been done before. Some people are having a hard time getting their head around this. I have even been advised this is wrong.

My original motivation for doing this was the web-bots that routinely look for a form at /user/register and fill it out. Almost all of these web-bots have valid e-mail address (thanks gmail.com! >:-( ). I was getting about 10 registrations a day before I tired of the experiment and just shut it off (Who can register accounts? - admin/config/people/accounts). The system would send an email - you will be approved just as soon as pigs fly, please be patient - just kidding - I wish I had done that - it was just the standard drupal wait for admin approval boilerplate.

Meanwhile, the site also has a menu item on every page that says Members. On the members page is a link to a page that allows immediate registration. Not one web-bot has been able to figure that one out yet.

Whew, long post.

Thank you so much, chrisroane, for taking the time to install it and poke around and for the generous feedback. Explaining it to you makes me better at explaining it the next time. Your time and effort is really appreciated and if I can ever do the same for you, I will.

-Dio

chrisroane’s picture

My suggestions were meant as just friendly suggestions (for the documentation and admin). I don't necessarily think they are absolutely required. I had found where all of the admin areas were after some poking around. But I didn't reference the help section, which would have helped a lot.

You bring up an interesting point about the code not having any drupal dependencies (that specific curl piece). Which allows the code to be re-used much more easily among multiple versions of drupal and outside of drupal. I've been working on drupal custom modules for a while, but I'm new to contributing to the drupal community. So I'm not sure if what you propose is okay. You definitely have your argument ironed out for it, though. :) I'm curious at what patrickd or klausi have to say about this.

prashantgoel’s picture

Status: Needs review » Needs work

please visit http://ventral.org/pareview/httpgitdrupalorgsandboxdiogenes1234042git for the list of errors being generated.

patrickd’s picture

Status: Needs work » Needs review

Don't set needs work on minor issues by automated review, this just blocks real reviews

andyg5000’s picture

Status: Needs review » Needs work

Review of D7 Branch:

To start, I think this module is a great idea and will be excited to try it out once it gets moved into production.

I don't think there is a rule that says your module folder name has to match your project name, but this is a pet peeve of mine. If I download a project called "members_page", I expect to be able to enable it by calling "drush en members_page". Also, it appears that theres already a members module, but it's long been abandoned so I don't know how that works with your module being named the same.

Note: Your module is coded differently than others that I've reviewed. The thoughts below are based on my experience with looking/working with other Drupal contrib modules.

Note2: This module was set as "needs review" when it should have been "needs work" some of these items have already been mentioned previously.

members.inc

There are a few coding standards issues that paraReview.sh should help you fix.

When enabling your module via drush en members I get the following echoed out in an endless loop:

<pre>connect() timed out!</pre>

I believe this is because your using $base_url which I don't think is available from drush unless it's set in the settings file (which I rarely do).

Would it be better to use the following instead of your CURL method? http://api.drupal.org/api/drupal/includes!path.inc/function/drupal_looku...

members.install:

As far as I'm aware, hook_install() should only be used to setup database schema's. I'm not sure why it's being used to define variables.

You're defining constants (MEMBERS_ANON_GREETING, MEMBERS_MEMBER_GREETING) to set up markup. I'd suggest some other way to create this markup so that they can be translated. I think it would be best to create template files. I see where these items can be overwritten in the settings pages, but at the least I think it would be best just to set the variables without defining constants.

The "while (TRUE) {" statements make me wanna barf :) it seems like drupal_lookup_path would clean up a lot of code in this module

The hook_uninstall is great!

members.module

Line 14:

The help information seems to be the same as the README.txt. Is it necessary to add this and is this the best method?

Line 102:

I'd recommend using t() for translation in your hook_menu title and descriptions.

Line:168, 189, 210 & 218

Follow coding standards when declaring functions (members_editAnonGreeting).

line 230:

What is the reasoning for setting class='node'. If users have the ability to edit the markup, then they should be able to declare their own styles and divs.

Line 259:

Do not use

Line 310:

Functions with leading underscores usually represent "private" functions and should not be called from other modules (_block_render_blocks)

I'm aborting this review at this point. I feel that there are too many updates/adjustments that need to be made to get this module into a reviewable state. I can tell you've spent a lot of time on this module and am not putting it down, but there are certain guidelines for drupal development that I feel haven't been followed in the 7.x-1.x branch of this module.

andyg5000’s picture

Issue summary: View changes

Revised to reflect name change and changes to module

Diogenes’s picture

Status: Needs work » Needs review
Issue tags: +authentication, +registeration approval

My apologies for taking 4 months to reply -- sometimes it takes some that long to recover from a random drive-by shooting code review.

Regarding your Note 2 -- it was me who last set the status back to needs review. A previous reviewer had mentioned that it did not install with DRUSH. I did respond to that issue, changed the code, and asked for a reply. I never heard back. Waited for 3 months.

Then you came along and repeated the same problems installing with DRUSH; with the module naming conventions; code constructs (they make you PUKE?), local variables in camelNotation, using _private functions and the recommended alternate drupal functions that you (and others) think might be a better choice. All of these points, except the last, have absolutely nothing to do with:

1) does the module work as described?
2) making it work better.

I waited 3 months for this?

On the last point above, I have tried every drupal function that was suggested. I wrote my own in simple non drupal php because the same code works in all versions of Drupal.

But we have established one thing for certain here:

THIS MODULE DOES NOT INSTALL WITH DRUSH.

I don't know why. I don't use DRUSH. And I don't care anymore.

I have committed new code. There are many changes. I can't wait for this ship to come in. There are still 'issues' with pareview but there always are. If not, just wait until the code gets reviewed. There will be new things.

If these reasons condemn this module to a perpetual 'needs work' status, then fine. This will be the last time I set the status here to 'needs review'. I'm cutting bait after this cast.

cubeinspire’s picture

Dear Diogenes,

I've been reading the reviews, installed your module and tested it.
As I understand one of the objectives of those reviews is to make the contributed modules work better.

The remarks are not there to annoy you but to improve your module's quality and that requires an active participation from both sides, the contributor and the reviewers.

From what I see there have been some remarks on this project, and some of them have been ignored, as using API to check a menu availability instead of making a call to curl_init().
(wich is why it your module doesn't work with drush).

Notice that not all servers have php curl installed and using this function is not advised, as it can lead to incompatibility to certain configurations.
Why use curl when there are functions on the API that are compatible with all server configurations.
Beside that it makes your module incompatible with drush.

Concerning the check of a physical file on that address (as having a /login-user/index.html file on the server), that is not much to be worried about as the url is converted by mod_rewrite, and in fact you are all the time accessing /index.php?q=login-user/ so the index.html will never be a problem.

Beside that I see that your module uses the constants in a strange way... storing long html content, that by the way is not using t().
Those constants are just called once, so why create a constant at all and not just concatenate the HTML code with some t() ?

From what I see following the advices of the reviewers leads to a (more or less) fast approval.
Trying to keep non standard code that is potentially problematic/dangerous leads to looong wait times.

What proves that the review system works as a quality/security filter.

Beside all that, I think your module is really near to get approved, from my point of view there are those two points left (the curl to be replaced with the proper API functions and to change the constants by properly formated html with t()).

Best regards,

Sergio

Fabianx’s picture

I agree with #32 that all variable_set can be removed from .install.

I know you don't care anymore, but here is how others do that:

Add a checkbox "Enable Members page" to your form.

Then add the proper validate (like you already have) to check if the default gotten via:

variable_get('register_users_url', 'register/users')

is still available.

That way the functionality is only enabled when your form can check for it :). ( that is how securepages does it btw. )

That way you circumvent all install problems (could just leave the cleanup of variables on uninstall), remove the problems with st vs $t, can remove the long HTML in the install file, etc. and it installs with drush ;-).

I don't agree with the usage of curl here either, but if the curl code is not run from install I don't see an issue in that as plenty of other contrib modules choose to use curl for something.

With some simple change in UX you can probably solve all technical problems.

Nice module idea! :)

bhosmer’s picture

@Diogenes, are you interested in continuing in the application process?

Diogenes’s picture

Fabianx and logicdesign, thank-you for the reviews and the support; bhosmer, thank-you for your interest.

My apologies for the delay. It has taken a while to get things sorted out. If I may cut to the chase here, there are two remaining issues:

  1. initializing variables in the .install file
  2. using the curl library instead of Drupal API functions.

Variable initialization

I have moved the variable initialization from the .install file to the .module file and simplified it for translation purposes. This is counter intuitive to my way of thinking and a compromise; but so be it. It required a handler and changes to 4 lines of code. Simple text shows up now instead of nicely formatted html. Otherwise the module functions exactly as it did before. I left the Drupal 6 version as is.

Drupal API vs curl

This module has a configurable hook_menu() url. This is a rather novel concept in Drupal. The url in this case is a system variable and it must be initialized to something. Imagine if it was nothing.

The Drupal API offers the following candidate functions that I either knew about or were suggested to me.

  1. drupal_lookup_path()
  2. menu_get_item()
  3. drupal_valid_path()
  4. drupal_http_request()

I tried them all.

When writing code, it is impossible (and ridiculous) to plan for all contingencies; but good practice to plan for some. On my own Drupal 7 website I have several url's that the Drupal CMS does not know about. This is quite easy to do. I made a special one just for this discussion...

http://sontag.ca/whenpigsfly/

Drupal does not know about this page. It's not in any drupal database table anywhere. Apache deals with this url before Drupal even has a chance to look at it. So any Drupal API that looks at the database is pretty pointless.

drupal_http_request() held promise and I really did try to make it work. But in the end I opted with a home grown function that made use of the PHP curl library.

There are two advantages to this. The function is very simple [13 lines for drupal_check_url_free() vs. 296 lines for drupal_http_request()] and the home grown version works with every release of Drupal (6,7 & 8).

In preparing this defense, I did a lot of testing. For any skeptics that remain, I have developed a couple of novelty modules to demonstrate how vulnerable Drupal is to url conflicts. Here are two new sandbox projects:

  1. When Pigs Fly
  2. Baboons Beware

The support page is here. For a quick install and test, download the package from either wpf-7.x-wtf.tar.gz or wpf-7.x-wtf.zip.

Review the code. Read the README file. Try it out. You may be surprised.

There are 3 levels of WPF url spoofing (I just made this up now)

  1. contributed module url
  2. url-alias
  3. subdirectory/index.php injection

The current Members Page code, as it stands, will pass any WPF permutation on install. It will also elegantly recover on a reconfigure after any WPF permutation is installed.

Name one other Drupal module that can do that.

So that function in question -- drupal_check_url_free($url) -- stands as is. It makes the PHP curl library install a requirement. And a drush install will FAIL (unless there is something that can be done that I don't know about).

About this code review process

This project has been held up because it did not install with drush. There are all kinds of reasons why this is and it has taken this long time to get sorted; but in the end, this is NOT a good reason to withhold approval. Installation with drush is not a criteria for approval, nor should it be for all kinds of reasons.

I am quite happy to document that this module will not install with drush and requires that the PHP curl library be installed. Not a problem.

I only ask that this be examined in all contexts. Maybe this is a problem with drush. Maybe this is a problem with Drupal. Despite the changes, the code works almost exactly the same as it did 10 months ago as long as one did not use drush to install it.

-Dio

Fabianx’s picture

For me to RTBC this, please now only change:

* Add a variable to enable the modules functionality
* Check for this variable in your menu() function and return early if FALSE (default)
* Remove the check from the install file
* Add the "Enable Members Page" checkbox to the configuration form
** Use #states property to show the rest only if enabled: http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.ht...
* On the form submit to enable it, validate if the URL is taken like you already do and only allow changing of the URL - if that works.

That should be a quick change, improves UX, allows disabling of functionality easily and temporarily and removes all logic from install.

CURL can be left in easily, no problem with that.

:-)

Diogenes’s picture

With all due respect, you are asking to add another step into the User Experience (UX). First the module must be enabled in /admin/modules and then another checkbox added to verify that the option selected is really what the administrator wanted when he/she/whatever enabled the module. Notice how many other modules do that.

What would Steve Jobs say? (I can't believe I just said that.)

This discussion could have been avoided altogether if no check was made at all, and a Drupal standard API (like drupal_valid_path) was used instead, which seems to be the preferred use-case with this Open Source Project.

I suggest that two versions be provided here. One that would install for drush users; the other would install for everybody else. On behalf of myself and the other 90% in the world that don't use Linux, my apologies for this inconvenience.

-Dio

P.S. will be seeking other opinions on this matter.

Fabianx’s picture

The problem is that the install part is a very bad environment to use API functions.

It is not a full blown drupal environment, but rather a limited bootstrap environment.

Securepages uses this approach.

Other alternatives:

* Ignore the path problem all together and trust that admins change the path - if it is taken (in 90% the cases the problem won't occur)

or

* Use $items['my-module-name/register'] as _one_ standard path
* Register the user supplied path in hook_menu_alter instead by moving the path around and check if it taken
** Maybe add message if its not taken

Both things are way easier (now also in terms of DX).

koppie’s picture

Status: Needs review » Needs work

I believe this needs to be marked "needs work" (see Fabian's comments above).

klausi’s picture

Status: Needs work » Closed (won't fix)

Closing due to lack of activity. Feel free to reopen if you are still working on this application.

If you reopen this please keep in mind that we are currently quite busy with all the project applications and I can only review projects with a review bonus. Please help me reviewing and I'll take a look at your project right away :-)

Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (found some problems with the project) or "reviewed & tested by the community" (found no major flaws).

Diogenes’s picture

Status: Closed (won't fix) » Needs review

OK - I made the switch from windows to linux.

This latest version will install with drush. A directory called members_page is created after downloading from the git repository. The module can be enabled, disabled and uninstalled with the following commands:

drush en members
drush dis members
drush pm-uninstall members.

The module will install with or without the curl library enabled. If the curl library is installed, then an additional check is made that will detect if a requested url (one that Drupal has no knowlege of) is being used.

Note that the function drupal_valid_path() returns TRUE for any path prefixed with 'http://sitename/' regardless of whether it exists or not. This, apparently, works as designed, something else I don't really understand.

There are still pareview errors, but none of them impact readbility or performance. Some I can't seem to get rid of, others I don't quite understand, and some I simply don't care about.

PA robot’s picture

Status: Needs review » Needs work

Link to the project page and git clone command are missing in the issue summary, please add them.

I'm a robot and this is an automated message from Project Applications Scraper.

PA robot’s picture

Issue summary: View changes

Added link to support web page, edited text.

Diogenes’s picture

Status: Needs work » Needs review

Fixed?

pagolo’s picture

Hi Diogenes,
I tested your module; it seems to work fine and be useful.
- automatic review: please test your module with coder and/or navigating to ventral.org; particularly, avoid camel case names and use lowercase and underscore instead.
- manual review: members_page() function doesn't support localization: it should be relatively easy to implement it. Also, you should give a way to change the output of the members_page() function. You could use a template and separate logic from layout.
I wish you a good job...
Paolo

musicalvegan0’s picture

VERY nice readme file. Every readme should be this way.

A few more issues to consider:

  • You still have quite a few issues according to http://ventral.org/pareview/. You should work to clean these up first.
  • Also, your git repository link should link to your actual git repo, like this: http://git.drupal.org/sandbox/Diogenes/1234042.git 7.x-1.x
  • I'm concerned about this: "A visitor who completes this form will be registered immediately without admin approval (but still subject to email verification) regardless of the current site settings." This seems like it should be an optional configuration option and disabled by default as it has security implications. I think it being separate from the site's current settings is fine so long as there is a way to disable/enable it.

Good luck!

musicalvegan0’s picture

Status: Needs review » Needs work

Forgot to change application status to "needs work."

Diogenes’s picture

Status: Closed (won't fix) » Needs work

So this module gets 2 reviews within 20 minutes after sitting in the queue for only a month? Is this a sign that things are improving?

@pagolo - Thank you for taking the time to do a manual review. Your comment on localization is a valid one but I consider it a feature request. I would be happy to implement this request if this module was approved and in use. At this point it's not. Allowing feature requests to a module waiting approval is just wrong - it adds unnecessary delays to a process that takes way too long already.

Also, you should give a way to change the output of the members_page() function.

The output of the members page can be changed -- I have no idea what you are referring to.

You could use a template and separate logic from layout.

It is true that some CSS styling rules are in the code, but this module generates it's own content that no other module or theme knows about. I have tested this module with over 20 different themes. It works with almost all those themes with just a few tweaks.

@musicalvegan0

Thank you for the review.

I'm concerned about this: "A visitor who completes this form will be registered immediately without admin approval (but still subject to email verification) regardless of the current site settings." This seems like it should be an optional configuration option and disabled by default as it has security implications. I think it being separate from the site's current settings is fine so long as there is a way to disable/enable it.

This works as designed. The user/registration url that is on every drupal site out there has become an open door to spambots. Almost every site now has automatic registration disabled because that's where the bots first look. The members page module provides an alternate url (that can be changed) to foil the bots. The standard urer/register url remains where it is and functioning like it did before. The members page provides an alternate url for registration.

An admin does not install and enable this module unless an alternate page is desired. You are asking for a two stage enable process here (install module, enable module, activate module) which simply adds complications to code, documentation and usability. I am going to disagree here. This is not a good reason to changes the status from needs review to needs work.

You still have quite a few issues according to http://ventral.org/pareview/. You should work to clean these up first.

There will always be issues with pareview. Every time I run it there is something new it complains about - though none of the warnings have anything to do with whether the module works or not, or performance, or readability. I started this project long before there was any pareview. The camel notation was used in 3 different versions (D6, D7, and D8). The variables that use the camel notation are local ones (private in OO terminology). I could change the offending uppercase letter to lowercase and it would pass pareview but diminish the readability. I could also add an underscore, but drupal has so many underscores that it makes it more difficult to parse some drupal hooks. The no camel notation is just a rule lacking in reason but loaded with subjectivity. - there are lots of contributed modules that use camel notation and nobody is demanding that they be changed..

And please don't get me started on having 81 characters on a line instead of 80, or have 3 spaces characters when 2 were expected, with the warning repeated for every offending line. I have indented some lines to make them more readable. So pareview knows better?

Pardon my age and experience here but I'm going to conclude with a YouTube clip from Monty Python and the Holy Grail...

Then shall thou count to three, no more, no less.
Three shall be the number thou shall count and the number of the counting shall be three.
Four thou shall not count nor shall thou count two excepting that thou then procceed to three.

Five is right out.

Pareview, while quite useful, has become Drupal's Holy Hand Grenade of Antioch for code reviews -- used far too often to deal with cute little bunnies.

Beware of those killer rabbits!

PA robot’s picture

Status: Needs work » Closed (won't fix)

Closing due to lack of activity. Feel free to reopen if you are still working on this application.

I'm a robot and this is an automated message from Project Applications Scraper.

Diogenes’s picture

Status: Needs work » Reviewed & tested by the community

I am setting this to RTBC myself. I know that breaks the rules but the fact is that NOBODY in the last year has found anything that does not work in this module. But everybody manages to find something good about it.

At one point it did not install with drush. It took a long time to find out why (I used to develop on a Windows platform) and there was only one reviewer who was helpful on why a drush install would not work. The others just complained. I switched to Linux this year and it was pretty easy after that to find an elegant solution that was much better than any of those suggested demanded in the reviews to get an RTBC.

One thing that really bothers me about this process is that if an applicant challenges what a reviewer has to say (after a switch from needs review to need work), the chances are excellent that you'll never hear from that reviewer again. Nobody likes to admit they are wrong. Or maybe they have already been promoted so doing more code reviews is now their lowest priority.

I have been offered all kind of suggestions about using alternative drupal calls that would be more in keeping with the Drupal standard. I really did try to do that, but Drupal has a few issues. Those functions did not work in my testing, so I crafted some that did. I even attempted to prove where Drupal would not work but none of that mattered.

In closing, the most important thing about a module is that it works as described and the documentation that decribes it. That it works out of the box. If someone can't break it or breech the security, then it is RTBC.

No reviewer has the right to suggest alternatives, or request features and hold a project app hostage until those demands are met. But that is what is happening here.

And that is simply wrong.

klausi’s picture

Assigned: Unassigned » klausi
Status: Reviewed & tested by the community » Needs review

I'll look at this now in the Project applications sprint

klausi’s picture

Assigned: klausi » Unassigned
Status: Needs review » Needs work

Sorry for the delay, but you have not listed any reviews of other project applications in your issue summary as strongly recommended in the application documentation.

Review of the 7.x-1.x branch:

  • ./members.inc: all functions should be prefixed with your module/theme name to avoid name clashes. See http://drupal.org/node/318#naming
    function drupal_render_magic_block($fields) {
    function drupal_check_url_free($url) {
    function _curl_check_url_free($url) {
    
  • Coder Sniffer has found some issues with your code (please check the Drupal coding standards). See attachment.
  • DrupalPractice has found some issues with your code, but could be false positives.
    
    FILE: /home/klausi/pareview_temp/members.inc
    --------------------------------------------------------------------------------
    FOUND 0 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
    --------------------------------------------------------------------------------
     99 | WARNING | Unused variable $content.
    --------------------------------------------------------------------------------
    
    
    FILE: /home/klausi/pareview_temp/members.module
    --------------------------------------------------------------------------------
    FOUND 0 ERROR(S) AND 3 WARNING(S) AFFECTING 3 LINE(S)
    --------------------------------------------------------------------------------
     754 | WARNING | Form error messages are user facing text and must run through
         |         | t() for translation
     764 | WARNING | Form error messages are user facing text and must run through
         |         | t() for translation
     770 | WARNING | Form error messages are user facing text and must run through
         |         | t() for translation
    --------------------------------------------------------------------------------
    

This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.

manual review:

  1. There is a very strange file .gitatributes committed, see http://drupalcode.org/sandbox/Diogenes/1234042.git/tree/refs/heads/7.x-1.x
  2. members.module: your module file is quite large, have you considered splitting the code up into *.pages.inc and *.admin.inc files?
  3. "'#prefix' => '<div style="float:left;clear:left;padding-right:30px;border:none">',": inline CSS is bad, please use a dedicated CSS file to style your forms.
  4. Notice: Undefined index: comment_forbidden in members_node_view() (line 856 of members.module). Please enable PHP notices in your development environment.
  5. members_node_view(): this is vulnerable to XSS exploits. If i enter a"><script>alert('XSS');</script></a><a href="foo as Members Page url I will get a nasty javascript popup as anonymous user. You need to sanitize user provided text before printing, make sure to read https://drupal.org/node/28984 again. This is not a security issue per se, as a higher level admin permission is required to inject the malicious snippet, but should be fixed anyway.
  6. _curl_check_url_free(): why do you need cURL and cannot use drupal_http_request()?

So the function names, constant names, the strange long file name and the XSS issue are application blockers right now.

klausi’s picture

FileSize
4.09 KB

Forgot attachment.

Diogenes’s picture

Status: Needs work » Needs review

Thank you for the review.

I am going to challenge you on 2 points here because that's all I have time for at the moment.

6) _curl_check_url_free(): why do you need cURL and cannot use drupal_http_request()?

There are 2 reasons:

  • drupal_http_request() fails under certain use cases. It is possible to have a valid site url that
    a Drupal system does not know about. I have already demonstrated this.
  • drupal_http_request() is either not available or consistent across versions 6,7 & 8 of the Drupal API

_curl_check_url_free() is a simple function (19 lines) that makes use of the php cURL library. It works with every version of Drupal unaltered.

drupal_http_request() in D7 is 203 lines long, invokes all kinds of other incantations and is hard to figure out.

Why is there a problem with cURL anyway? A standard php install adds it in by default and most shared service providers include it as well. It's unfortunate drush has an issue with it but that is really minor and has been fixed anyway.

5) members_node_view(): this is vulnerable to XSS exploits

I thought that might come up but I left it as is, for a reason. The input field you speak of is an administration field that should only have sys admin authority. I consider sanitizing this input to be over-the-top security that will serve little good and may only restrict an admin.

The Members Page module creates an alternative page to /user/register at an available url of your choosing. The /user/register url remains functional as before and can be used as a honeypot if desired.

I don't wish to restrict a capable sys admin from inventing a url that is really hard for spambots to adjust to, only to have it filtered out because some other mother knows best.

Hoping for a response soon.

I promise to start doing code reviews too. Kinda busy right now.

kscheirer’s picture

Assigned: Unassigned » kscheirer

I'll look at this now in the Project applications sprint.

----
Top Shelf Modules - Crafted, Curated, Contributed.

kscheirer’s picture

Title: Members Page » [D7] Members Page
Status: Needs review » Needs work

Thanks for sticking with us so long Diogenes, it obviously has not been a great process but we're working on it! I can't do anything about what's happened up til now, but I'll commit to reviewing this application as long as you're still working with us.

Blocking Issues:

  • Remove .gitattributes and .gitignore
  • XSS problem - we have docs at https://drupal.org/node/28984 (under Admin-only HTML). A filter_xss_admin() call should be sufficient. You may think it's over the top, but we try very hard to avoid security issues wherever possible. Just making sure it's a valid url should be sufficient, instead of allowing script tags.
  • Your constants should be namespaced to your module, so VISITOR should be MEMBERS_VISITOR.
  • All the members.inc functions should be namespaced to your module (member_*). You can open a separate issue to get them added to core, but until then they belong in this module's namespace.
  • In members_block_view_alter() use theme('username') instead of printing $user->name directly.

Other Issues:

  • We don't use camelCase in D7, this applies all over and to members_editMemberGreeting, members_editAnonGreeting, $panelWidth, &c.
  • cURL isn't always installed, but you're free to use it. hook_requirements() is the way to check for it though. We recommend drupal_http_request() to most people as they often find it easier to use.
  • Your project page refers to screenshots at the bottom, but I didn't find any. edit: I see, they're at http://sontag.ca/drupal/members-page-module, can you add the link? That page is nicely documented!
  • "A visitor who completes this form will be registered immediately without admin approval (but still subject to email verification) regardless of the current site settings." - why disregard the current settings?
  • In members_install() why do you need any drush messages? Drush is generally able to install modules and will report the status to a command line user.
  • If you have requirements like curl, use hook_requirements() instead, this will get added to the status report page.
  • You don't need a bare include 'members.inc'; at the top of your module file, just include_once where you need it.
  • Instead of style="float:left;width:47%;padding:0 8px;border-right:solid grey 1px" use a css file.
  • Why does $members_path . '/view' menu item use access 'edit member page greeting', when it looks like $members_path . '/edit/member' is where that happens?
  • Your styled forms should use a #theme function or template, that way others can override your settings without having to resort to a hook_form_alter().
  • Instead of the 2 editGreeting functions and their submit handlers, can you use a single admin form using system_settings_form() - that will handle the variable_set()s for you as well.
  • In members_page() use a theme function or template if possible. Instead of creating links manually, use l() or url().

----
Top Shelf Modules - Crafted, Curated, Contributed.

Diogenes’s picture

I'll commit to reviewing this application as long as you're still working with us.

Thank you for making that commitment. I think this should be a "Best Practice" for PA code reviews. In a master/apprentice relationship, the master teaches the apprentice. The apprentice can ask questions (like why) and the master should be able to answer those questions in such a way that apprentice understands why. If that fails, either the apprentice is not cut out to be a master or the master has an apprentice that is about to change the craft by challenging the way things have been done in the past.

There is nothing more frustrating in this process than challenging a review on a premise or assertion made by a reviewer, and then not recieving an answer.

Let me put it another way. A reviewer can do a lot of work in reviewing a module (or very little). There may be some excellent points made in the review. But if an applicant challenges a point made by a reviewer and the the reviewer never acknowkledges or responds to that challenge, then that review isn't worth a bucket of shit. It's just an opinion of someone who cannot be bothered to defend it.

Please consider this and discuss this with your collegues. There is much room for improvement in this process.

=================================

I will now address the blocking issues, point by point.

1) Remove .gitattributes and .gitignore

Agreed. But a little history first. I added the .gitattributes after someone decided that all files must end in unix style LF terminators (including the .txt files). I used to develop on a windows system. I now have a dual boot Windows/Linux system with a common NTFS partition with the Drupal code base.

I was using git for windows, uploading and downloading to the Drupal git repository WITHOUT A PROBLEM. This is because git elegantly handles the OS native mode EOL by default. So does almost every text editor I have used. It does not matter if it is LF, CR/LF or CR.

Then I run an updated coder in windows, and guess what, it complains about the README.txt file ending in CR/LF. My editor had an option to save with unix EOL, so I swiitched that on. Of course any file I updated and saved after that triggered a changed that affect the whole file and not just the line I changed. More havoc was created when I switched to back unix.

That mysterious .gitattributes files came from http://stackoverflow.com/questions/170961/whats-the-best-crlf-handling-s.... It solved most of the problems I had.

The arbitrary decision to enforce unix style EOL caused me and others to reconfigure things, download new plugins, get new files, that WERE TOTALLY UNNECESSARY because others, including the authors of GIT and most every other editor, already handled it without a problem. GIT, by default, handles native mode EOL conversions for the client. It does not matter what platform the developer uses, GIT converts any push to unix style EOL for the repository.

The unix only EOL rule added to the coder module WAS A MISTAKE. There were no problems it caused to begin with but there were many unintended conequences as a result.

I know enough about human nature to know this decision will probably never be reversed, but hopefully others will think about such "great ideas" and run them by the membership before SHOVING IT DOWN OUR THROATS.

Ooo - Long post - saving now so this effort does not go to that big bit bucket in the sky!

To Be Continued...

Diogenes’s picture

Continued ...

2) XSS problem

OK - I'll add in the filter_xss_admin() but your explanation as to why it is necessary is not very convincing. I'd prefer some better answers than "we try hard".

3) NAMESPACES
OK - I'll change these too. But this is the first time this issue has ever been mentioned on the defines. The function drupal_check_url_free() was named that way because Drupal does need a function like this if paths can be reconfigured. And NO -- drupal_http_request() does not work for this purpose.

4) Use theme(username) instead of $user->name directly

OK - I'll do this too. But this is also the first time this has been mentioned in any review which illustrates just how subjective these code reviews can be.

If you look at the standard D7 User Menu block, you may notice that it does not list the User name. D6 did. I thought it was a nice touch, so I added this to my module. Using theme(username) instead of $user->name add little value here. It may be the 'Drupal way', but calling this a blocking issue and delaying approval of this module for this reason is over-the-top political correctness.

I want to discuss the other issues raised but this is enough for now.

Will push an update in a day or 2.

Diogenes’s picture

Status: Needs work » Needs review

Updated and ready for review. Sorry for the delay. I have very been busy with other things.

All of the blocking issues have been fixed and, for good measure, I also added a theme function, a template file and a CSS file to the module; removed the markup and style rules from the code; and changed the camelCase notation and function names to match the Drupal standard.

It was more work than I expected. The module produces the exact same html as it did 9 months ago, just in a slightly different fashion.

I have not added CURL to a hook_requirements() call because cURL is not required -- the module simply works better with cURL installed.

Other Issues:

"A visitor who completes this form will be registered immediately without admin approval (but still subject to email verification) regardless of the current site settings." - why disregard the current settings?

The Members Page module does not affect the behavior of the standard user/register page. This is by design. It is intended to be an alternative to user/register. The user/register page can be disabled, or enabled with/without admin approval as before. If the user/register page is enabled without admin approval, then there is really no point in having the Members Page module enabled. A warning message is posted in this case.

cURL isn't always installed, but you're free to use it. hook_requirements() is the way to check for it though. We recommend drupal_http_request() to most people as they often find it easier to use.

kscheirer - please read #35 and the first point on #53.

I can't speak for most, but not everyone finds drupal_http_request() easy to use. It's very different in D6 and not even available in D8.

I offer a very simple solution that works with all versions of Drupal. And I keep being told that is wrong, that I really should use a 200+ line function that does not work in some cases, but since it has drupal in the name, it must be good.

Maybe I'm just in the wrong universe. Maybe i don't believe in the right gods or have enough faith.

Maybe I just don't belong here.

kscheirer’s picture

Status: Needs review » Reviewed & tested by the community

Blocking Issues:

  • Remove .gitattributes and .gitignore
  • XSS problem - we have docs at https://drupal.org/node/28984 (under Admin-only HTML). A filter_xss_admin() call should be sufficient. You may think it's over the top, but we try very hard to avoid security issues wherever possible. Just making sure it's a valid url should be sufficient, instead of allowing script tags.
  • Your constants should be namespaced to your module, so VISITOR should be MEMBERS_VISITOR.
  • All the members.inc functions should be namespaced to your module (member_*). You can open a separate issue to get them added to core, but until then they belong in this module's namespace.
  • In members_block_view_alter() use theme('username') instead of printing $user->name directly.

Thanks for fixing those plus a bunch more.

----
Top Shelf Modules - Crafted, Curated, Contributed.

Diogenes’s picture

Thank you for the RTBC kscheirer.

For what it's worth, I was impressed by how thorough you were in post #55, even if I initially just expressed my outrage. I admire your knowledge and pluck sir, you followed through like you said you would.

High regards,
-Dio

kscheirer’s picture

Assigned: kscheirer » Unassigned

Sure thing Diogenes. I'm taking my name off so someone else will give this the final review, but I'm still keeping an eye on it.

kscheirer’s picture

Just to let you know, I'll promote this project on Sep 28 if there are no further comments. I don't normally fix my own issues, but it's allowed in this queue if it's been waiting in RTBC for a month.

----
Top Shelf Modules - Crafted, Curated, Contributed.

drupaledmonk’s picture

I have been using the 7.x branch in 2 sites and waiting for it to be a full fledged project. Thanks for the contribution.

kscheirer’s picture

Status: Reviewed & tested by the community » Fixed

Sounds good, thanks for the review!

Diogenes, thanks for your patience, the process obviously did not work well in your case. We do have a discussion group for improvements here: https://groups.drupal.org/code-review. And a spot specifically for reviewee's stories: https://groups.drupal.org/node/142464. There have been a lot of improvements made since this application was started. Suggestions for improving How to review Full Project applications are also welcomed.

Thanks for your contribution, Diogenes!

I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.

Here are some recommended readings to help with excellent maintainership:

You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!

Thanks, 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.

Thanks to the dedicated reviewer(s) as well.

----
Top Shelf Modules - Crafted, Curated, Contributed.

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

Anonymous’s picture

Issue summary: View changes

Add links to project page and git instructions