Roost for Drupal brings the power of web push desktop notifications to any Drupal based website or application. Desktop push notifications have become very popular when Apple released Safari on OS X Mavericks.

Roost provides a simple way to integrate this into your site. For a quick overview of Roost and web push, check out this video: https://vimeo.com/88533265

The Roost for Drupal module does all of the hard work. Once activated, and signed into the module, the required JavaScript is injected into your site's pages. Users will now begin receiving prompts to allow / disallow notifications.

The module adds more power by adding an "Auto Push" option when creating an Article or Blog Post. This setting can be turned on or off from the module's configuration page. Also added by the module, in the configuration page, is a way to manually send notifications from within Drupal, and see your Roost account stats. This means a person never has to leave their Drupal site to engage their site visitors.

Roost for Drupal is free. A Roost account is needed, but the service is also free.

Here is a link to the Project Page
https://drupal.org/sandbox/noticesoftware/2223357

Here is a link for the git repo
http://git.drupal.org/sandbox/noticesoftware/2223357.git

Reviews of other projects (Review Bonus #1:

Reviews of other projects (Review Bonus #2:

Comments

GoRoost’s picture

Issue summary: View changes
PA robot’s picture

We are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will 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" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).

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

clayfreeman’s picture

Status: Needs review » Reviewed & tested by the community

Seems to work well within expected parameters. I will look forward to using this module once it has a stable release.

All PAReview tests passed with flying colors, and everything else seems to be in order.

GoRoost’s picture

Thanks for the review @clayfreeman. Excited to get this rolling.

rcross’s picture

Please provide some details on the project page about the module. Here are some tips on how to do that https://drupal.org/node/997024

GoRoost’s picture

Description and some screenshots and resources have been added. Thanks @rcross.

GoRoost’s picture

Issue summary: View changes
Issue tags: +PAreview: review bonus

Updated adding links for PAReview bonus.

rcross’s picture

A few minor suggestions:

* The link for a demo is to a video. It would be better to have a link to a working example and have the video in the body description.
* The "utility" category doesn't seem a good fit.
* The description might benefit from a common use case. I think I can see its uses, but other people might not. It will also help people who might search for these areas, but not be familiar with roost.

I have not trial run the module, but otherwise this seems like its ready to me.

Possibly a bit more appropriate after it has been approved, but would be great to also have an issue or section in the description that highlights what is left to be done before a stable release is ready.

GoRoost’s picture

Thanks for the feedback and review @rcross. I'll review and makes those changes tomorrow.

GoRoost’s picture

@rcross - Hoping that this can get reviewed and approved soon... Updated the categories per your suggestion. Removed "Utility," but added "Mail." This appeared fitting as other forms of social share modules are included in the category.

Also added a "Common Use Case" paragraph explaining the work flow.

We do have a laundry list of new features and updates that will be attached, that will be added once approved.

rcross’s picture

the mail category is not appropriate in my opinion as I see nothing related to email functionality. The use of categories is not to select as many as applicable, it is also not a commonly used method of module discovery.

My other points still stand regarding the demo link and the module roadmap.

I also think the use case could be improved, as it is currently written it seems quite similar to describing the functionality rather than *Why* someone would want to use this module. what are some common scenarios? ie. As a x-type user, I want to Y-something to achieve Z-result. This module helps achieve this by doing W

GoRoost’s picture

@rcross - Removed non-relevant category.

klausi’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -PAreview: review bonus +PAreview: security

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

  • Coder Sniffer has found some issues with your code (please check the Drupal coding standards).
    FILE: /home/klausi/pareview_temp/js/roost.js
    --------------------------------------------------------------------------------
    FOUND 1 ERROR AFFECTING 1 LINE
    --------------------------------------------------------------------------------
     1 | ERROR | Missing file doc comment
    --------------------------------------------------------------------------------
    
    FILE: /home/klausi/pareview_temp/js/roost.admin.js
    --------------------------------------------------------------------------------
    FOUND 1 ERROR AFFECTING 1 LINE
    --------------------------------------------------------------------------------
     1 | ERROR | Missing file doc comment
    --------------------------------------------------------------------------------
    
    FILE: /home/klausi/pareview_temp/roost.admin.inc
    --------------------------------------------------------------------------------
    FOUND 1 ERROR AFFECTING 1 LINE
    --------------------------------------------------------------------------------
     6 | ERROR | There must be exactly one blank line after the file comment
    --------------------------------------------------------------------------------
    

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. roost_menu(): doc block is wrong, this is a hook_implementation. See https://drupal.org/node/1354#hookimpl . Also elsewhere.
  2. roost_page_alter(): do not drupal_add_js() here, use #attached on the render array that this hook receives. See https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.h... . Same in roost_admin_form().
  3. roost_node_insert(): are you sure you want to use hook_node_insert()? You should rather register your own submit handler in roost_form_alter(). If any node is inserted programmatically and is not a page, then you will send out a notification, which might not be desirable.
  4. roost_node_insert(): this does not seem to respect node access? What if a private node is inserted? Then a notification will go out pointing to a node where the users don't have access to? The URL alias and the node title disclose information of the private node, so this is a security issue. I would suggest to check if 1) the node is published and 2) the anonymous user has access to it. And please don't remove the security tag, we keep that for statistics and to show examples of security problems.
  5. roost_node_insert(): do not call drupal_lookup_path(), just use url() to get the automatically aliased URL of the node.
  6. roost_module_implements_alter(): why is that needed? Why does your hook have to run last? Please add a comment.
  7. roost_admin_form(): drupal_strip_dangerous_protocols() is useless here since you can always trust your own base_url.
  8. "'#value' => 'Login',": all user facing text must run through t() for translation. Same for "'#value' => 'Continue',", please check all your strings.
  9. '#markup' => '<div id="roost_user">' . variable_get('roost_name', '') . '</div>',: This is vulnerable to XSS exploits. The roost_name is user provided text and needs to be sanitized before printing to HTML. This is not a critical security issue since the "administer site configuration" permission is required, which is on the policy white list at https://drupal.org/security-advisory-policy . You should fix it anyway and make sure to read https://drupal.org/node/28984 again.
  10. "'placeholder' => 'Enter message URL (http://mysite.com)'": that placeholder needs to be translated as well, right? Same for "$status = 'Message Sent.';".

Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

GoRoost’s picture

@klausi

Added Doc comments for:
- roost.js
- roost.admin.js

Removed additional blank line after comment for:
- roost.admin.inc

1. Complete - Function comments updated per API documentation and comment standards
2a. Updated - roost_admin_form() to use #attached on render array
2b. Note - Changed roost_page_alter() to use hook_init() (roost_init()) - used to include JavaScript and var site wide, required for integration. Also checking if admin page, as not necessary in admin area
3. Note - This is a deliberate choice. This module has two use cases, sending notifications from the Admin dashboard, and our “Auto Post” option that is triggered upon creation of a node. There is an override checkbox to not send when creating a node, to satisfy your statement of possible undesired behavior
4. Complete - Checking the status of the node before sending notification
5. Complete - Updated to use url() with absolute path
6. Note - Not necessary, hook removed.
7. Complete - Unnecessary function removed
8. Complete - Plan text run through translation
9. Complete - Text inserted into html is run through check_plain()
10. Complete - Plan text run through translation t()

GoRoost’s picture

Status: Needs work » Needs review

Updated status to "Needs review"

kvnm’s picture

Status: Needs review » Needs work

Hi Roost.Me,

I like this. It's simple to get going, straightforward to use, and cute as well as useful. Code is very clean and well-organized.

  1. Code sniffer is still upset about your docblock comments on .js files. Check out https://drupal.org/node/1354#files. You should just need to add @file in there and you'll be good to go.
  2. The only thing that I think should absolutely be added is a way for admins to choose which content types send Roost notifications. Right now, the hook_form_alter() that add the on-the-fly option to send notifications is limited to articles and blogs. Additionally, roost_node_insert() looks to send notifications for ALL content types EXCEPT basic pages. This would hamstring many Drupal site builds wishing to use your notifications, and force site builders to hack your module in order to make it work for their needs.
  3. Additionally, I would find it helpful if there was a permission in place for viewing the node-by-node not_send option. That way, admins could choose which content types are able to send notifications, and allow them to make use of roles and permissions to accommodate more personalized workflows. I would say that's a feature request, though, not an RTBC-blocker.
  4. Lastly, I agree with klausi's #4 item. At a minimum, I would think that you might only send notifications when content is first published as opposed to when it's first saved. Saving unpublished content is pretty common on Drupal sites. If admins must always opt that content out if they want to, say, come back to polish up their post later, I think it'd be easy to accidentally forget and wind up sending notifications out for inaccessible content. Also, hook_node_insert() will only be called the very first time the node is inserted into the db, so if a content admin wanted to save a draft to work on later, it becomes impossible to send notifications for that node when it's finally ready.
GoRoost’s picture

Status: Needs work » Needs review

@kvnm

Thanks for the kind words.

1. Done!

2. This is definitely a feature that we do intend to add, and I see the value, but disagree that this is necessary to publish. We are purposely limiting to Articles and Blog Posts for one, simplicity sake with an MVP for this module, and two, thus far our success as a standalone product and in other integrations has been with content publishers. Bloggers, news institutions, etc.

Opening it up to all type could also cause accidental collisions. We had this situation with another integration where an automated Twitter plugin was triggering multiple notifications.

NOTE - Changed restrictions from NOT basic page to ONLY Article and Blog Post to satisfy reverse of original comment.

3. Agree with this, also view this as a feature, and will place on the TODO once we’re published.

4. Good point about hook_node_insert(). Changed to use both hook_node_insert() and hook_node_update(). Both will fire a function to build the notification and send it if $node->status = TRUE and the node is not private.

kvnm’s picture

2. Fair enough. The module does work well, so I agree this could be a feature to be added later. However, I definitely think that this feature is essential to adoption. It's very common for site builders to create their own content types for content publishers to use. I've personally done this dozens of times. At a minimum, when the project launches, it seems like you should mention the Article/Blog-only factor in a README as well as on the project page for folks who don't want to/don't have the ability to root through the module's code.

4. Great-- this is definitely an improvement. However, since the check in roost_build_note() only checks status, and not whether the status has changed to 1, this means that every single update (unless opted out) to a given node that's already been published will trigger a Roost notification. Is this intentional? You might tack on something like this: http://drupal.stackexchange.com/a/6131, as the original status is actually tacked onto the node entity.

GoRoost’s picture

@kvnm

I really appreciate the prompt feedback. Huge help here. Can not wait to get this published...

2.) When the project launches, yes, we will provide full instructions / documentation as well as planned features.

4.) Your stackexchange link was very helpful. It is not desired behavior to publish on every update / save. Added a check on the $node->original->status in the hook_update_node() function to take care of this. Additionally, added checks on the hook_form_alter() to show / hide the Roost Override Notification checkbox. It is now hidden if a post is published, and shown if it is new, or in the unpublished state.

Also, Code Sniffer keeps complaining that I do not have a @file block in my .js files, however they are clearly there, and clearly match what is referred to in the Drupal commenting standards, as well as how other plugins do it.

Hoping for a RBTC status update.

kvnm’s picture

Status: Needs review » Reviewed & tested by the community

Cool, your changes look good and they work for me.

GoRoost’s picture

Thanks @kvnm. Appreciate the leg work you've been doing.

GoRoost’s picture

Issue summary: View changes
Issue tags: +PAreview: review bonus
mpdonadio’s picture

Status: Reviewed & tested by the community » Needs work
Automated Review
No issues; false positives.
Manual Review

One note on the licensing thing. As this is your service, and since this will end up being GPL, the logo image file
will therefore be GPL.

There are some CSS errors (eg, line 155). In addition, some of the rules are scoped too generic and may interfere with
other modules (eg, line 154, 158)

Drupal.behaviors.roost doesn't use the context that was passed to it for the jQuery. See https://drupal.org/node/751744

In roost_install() you don't need to do the variable_set(), just use the default when you variable_get().

The functions in roost.api.inc should have proper docblocks w/ paramater and return value information.

You don't need to specify the access callback in roost_menu(); user_access is the default.

Long term, I would create your own permission for administering things.

roost_form_alter() may catch non-node forms. Look into the hook_form_FORM_ID_alter() version of the hook (I think roost_form_node_form_alter will do the trick).

I agree that limiting this to certain content types will limit the reach of this module. The Blog module is also legacy module
provided for backward compatability. Personally, I don't know anyone who uses this directly (we always roll our own blogs).

Avoid using hook_init(), this runs for all Drupal requests, including non-HTML ones. hook_page_build() is likely better.

roost_form_alter() has an untraslated string (the #title).

Use NODE_PUBLISHED and NODE_NOT_PUBLISHED instead of the values, and don't compare $node->status with TRUE.

Instead of using the hook_node_insert() and hook_node_update() hooks, I would implement as a Rules action,
as Rules is pretty ubiquitous on Drupal sites.

Using $nid instead of $id really is the defato username. This makes it easier for other people to read the code.

In, roost_build_note(), you are directly accecssing $_POST['not_send']. This is a bad idea in Drupal. This would be a security issue
if you were actually using the value, but in this case the insert/update hook may be invoked from places other than the node forms,
eg, publishing from admin/content, or scheduled publishing (which is common for your use cases).

The roost_admin_page() function is somewhat similar in name to hook_admin_paths(). Personally, I would rename this.

Personally, I'm not terribly keen on the roost_admin_page() swapping out different forms. I would use a single
form w/ disabled elements based on whether you are authenticated or not.

roost_admin_form() doesn't look like a hook_form(). If not, then your docblock and form argument names are wrong. Same with roost_plugin_form().

roost_admin_form_submit(), you don't need to plain on line 145. Nothing is coming from user input there (and @placeholders in t() would be take care of).

Check out format_plural(). You may be able to use it.

roost_build_note() is adding ->roosted directly on the $node. Look into adding this as a proper entity
property. This also looks unused right now.

(*) The access check in roost_build_note() is wrong. This will run in the context of the publisher, not the
user viewing it. You need to do something like

$public = node_access('view', $node, drupal_anonymous_user());

The starred (*) items are blockers. The rest of the comments in the code walkthrough are recommendations. Please don't remove the security tag, we keep that for statistics and to show examples of security problems.

GoRoost’s picture

Status: Needs work » Reviewed & tested by the community

@mpdonadio Thanks for the quick review! Hope to keep this pace up.

I addressed your blockers as well as a few others. Completed items so far are:

  • DONE Use $nid instead of $id
  • DONE (*) The access check in roost_build_note() is wrong. This will run in the context of the publisher, not the
user viewing it.
  • DONE roost_form_alter() has an untraslated string (the #title).
  • DONE roost_admin_form_submit(), you don't need to plain on line 145.
  • DONE There are some CSS errors (eg, line 155). And generic scope

Would like to get this approved and published, then continue woking on remaining items.

mpdonadio’s picture

Status: Reviewed & tested by the community » Needs review

Setting back to Needs Review, as the changes need to be reviewed before RTBC.

PA robot’s picture

Status: Needs review » Needs work

There are some errors reported by automated review tools, did you already check them? See http://pareview.sh/pareview/httpgitdrupalorgsandboxnoticesoftware2223357git

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

GoRoost’s picture

Re @PA robot (Yes I know it's a robot)

Per @mpdonadio and self-review, Automated errors are a false positive.

GoRoost’s picture

Status: Needs work » Needs review

Changing to Needs review - PA Robot was wrong.

klausi’s picture

Assigned: GoRoost » mpdonadio
Status: Needs review » Reviewed & tested by the community

manual review:

  1. hook_init() is still there as reported by mpdonandio, which should be hook_page_build() instead. Also the other stuff mentioned by mpdonadio does not seem to be fixed.
  2. "Select which site do you want to access ...": all user facing text must run through t() for translation. Please check all your strings, there still lots of instances where t() is needed.
  3. "drupal_set_message(t('Please check your Email or Username and Password.'));": Usability: this appears as a status message and not as a form error. You should not validate the API credentials in the submit callback, but rather in a validate callback where you can use the regular form_set_error() function. https://www.drupal.org/node/751826 docs are for D6, but mostly applies for D7 as well.

All in all quite a few major issues that should be cleared up, but not critical application blocker, therefore looks RTBC to me.

Assigning to mpdonadio as he already looked at this once and can do the final signoff.

GoRoost’s picture

@klausi - Thanks for the review and the RTBC status.

I have a few of the other fixes mpdonadio mentioned already taken care of, just waiting and hoping to get approval and push fixes after to avoid further delay.

mpdonadio’s picture

Assigned: mpdonadio » Unassigned
Status: Reviewed & tested by the community » Fixed

I took one more pass through this, and I stand by my review and the few additional things that klausi mentioned. None are blockers, but I really think that as much from the list should be taken care of as possible. Apart from the Drupal best practices (eg, the hook_init() and the validation), your anticipated uses cases will limit the scope of the module. For example, we have a site launching soon which will include job listings, which are implemented as a specific content type. I can see these being desired for push notifications. I also work with clients who use workflow and scheduled publishing, so having this only work from the node forms will limit its use, too. But, that is just friendly advice, and not something to hold this up, so...

Thanks for your contribution, Roost.Me!

I updated your account so you can 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 stay 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.

Status: Fixed » Closed (fixed)

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