https://www.drupal.org/sandbox/cfischer83/2405355

Synopsis

The Mini Blocks module allows administrators to create simple key/value elements similar to typical Drupal Blocks, but with named keys rather than auto-increment integers. This allows admins/content editors to create editable pieces of content with "keys" that can be programmatically called based on their names.

Requirements

None

N/A

Known problems

Module always defaults to allow PHP code, so apply permissions with caution.

Pledges

Plans are to have a Drupal 8 version by March!

Credits

Cory Fischer: cfischer83

blocks — cannot be called by predictable keys
bean — Mini Blocks is intended to to be simple first, and called within areas of code such as WITHIN blocks or beans.
boxes — Boxes are meant to add functionality TO blocks, while Mini Blocks intentions are to remain completely independent without affecting the core functionality of blocks.

git clone

git clone --branch 7.x-1.x http://git.drupal.org/sandbox/cfischer83/2405355.git mini_blocks
cd mini_blocks

Automated Review

http://pareview.sh/pareview/httpgitdrupalorgsandboxcfischer832405355git

Manual reviews of other projects

Comments

cfischer83’s picture

Title: D7 Mini Blocks » [D7] Mini Blocks
Project: Mini Blocks » Drupal.org security advisory coverage applications
Component: Code » module
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.

Valentine94’s picture

Status: Needs review » Needs work

Looks not bad, but as for me it's not a good solution to write a HTML code in PHP functions, would be much better to use a theme() function and create a templates for your blocks.

cfischer83’s picture

Status: Needs work » Needs review

@Valentine94 I've implemented your suggestion. Thanks for the advice, it's much cleaner now!

cfischer83’s picture

Issue summary: View changes
cfischer83’s picture

Issue summary: View changes
cfischer83’s picture

Issue tags: +PAReview: review bonus
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/httpgitdrupalorgsandboxcfischer832405355git

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

Valentine94’s picture

38 | WARNING | Only string literals should be passed to t() where possible
Can be fixed by this way:
Just use this:

$label   = (arg(3) == 'edit') ? t('Edit') : t('Add');

And

'#title' => $label . ' mini block',

Rather this one:

$label   = (arg(3) == 'edit') ? 'Edit' : 'Add';

And

'#title' => t($label . ' mini block'),

87 | WARNING | Only string literals should be passed to t() where possible
I don't think that this can be fixed, so you should remove t() or ignore this warning.

11 | WARNING | Unused variable $k.
Just remove $k variable from the foreach.

Hope this help you.

Regards, Valentine.

joachim’s picture

> boxes — Boxes are meant to add functionality TO blocks, while Mini Blocks intentions are to remain completely independent without affecting the core functionality of blocks.

It's true that boxes can add functionality, but you can also have plain boxes that only hold content. And these have named block IDs.

cfischer83’s picture

Status: Needs work » Needs review

@Valentine94, thanks for the suggestion. This has been implemented on the most recent push.

Pareview now shows no errors.

@joachim I love boxes, but the way they are designed makes my blocks list verbose. I wanted to separate blocks/boxes (which typically have a paragraph or more) with mini blocks (which typically are more like labels for short bits of content... I almost considered calling this module label_maker).

Thanks for all the help!

Valentine94’s picture

Status: Needs review » Reviewed & tested by the community

Looks good for me :)

joachim’s picture

Status: Reviewed & tested by the community » Needs work
  // Create an object of type SelectQuery.
  $query = db_select('mini_blocks', 'mb');

  // Add extra detail to this query object: a condition, fields and a range.
  $query
    ->condition('mb.mb_id', $block, '=')
    ->fields('mb', array('mb_id', 'mb_value', 'uid', 'mb_date'))
    ->range(0, 1);
  $result = $query->execute()->fetchAll();

Don't use a dynamic query here: it's a simple query and it needs to be fast.

function mini_blocks_add() {
  $add_edit = (arg(3) == 'add') ? "Add" : "Edit";

Don't use arg() here: pass a parameter in from hook_menu().

Also, you could completely dispense with this function by using drupal_get_form() as the hook_menu() callback, and making your theme function tie in with the form builder.

function mini_blocks_admin_add($form = NULL, &$form_state = NULL, $defaults = array()) {

That's not the standard signature for form builder params. It's also good practice to suffix a form builder with _form for clarity.

  $label   = (arg(3) == 'edit') ? t('Edit') : t('Add');

Same as above: pass this in.

  $form['add_block'] = array(
    '#type' => 'fieldset',

There's no need for a fieldset at the top level of the form.

  // Must be unique unless editing.
  if (
    arg(3) != 'edit'
    ||
    $key != $key_original
    ) {
    if (count(mini_blocks_load($key)) > 0) {
      form_set_error('mini_block_key', t('Key has already been used'));
    }
  }

What if I'm editing block foo, and change its key to bar, and bar exists?
Don't use arg() -- instead, set a hidden form value is_new or something -- see how entity forms handle this.

    drupal_goto('admin/structure/mini-blocks', array('query' => array('msg' => 'success')));

The query string seems weird.

Also, don't use drupal_goto() in a form submit: use the form redirect system.

        'mb_date' => REQUEST_TIME,

You're updating the date on the block too. Is this then an updated timestamp rather than a created timestamp? Ditto the uid: that's the last user to edit. Both of these are unlike how other things work in Drupal, so worth commenting on to prevent confusion.

<article id="main-mini-blocks-add">
  <h2 style="font-size: 24px;"><?php print $add_edit; ?> Mini Block</h2>
  <p><?php print l(t("« List Mini Block"), 'admin/structure/mini-blocks'); ?></p>
  <?php print $form; ?>
</article>

It's not usual at all to use a tpl file for something like a form, especially if all you're doing it printing out the form!

Also, you're repeating the page title, and showing a link to the list page that's pointless because you have the breadcrumb and the tabs.

As for the view all TPL:

- You shouldn't make the 'Add Mini Block' in the theme -- use the menu system for this. See MENU_LOCAL_ACTION.
- use theme_table(), not raw HTML

When I install the module and go to the admin page, I get these errors:


    Notice: Undefined variable: rows in include() (line 18 of /Users/joachim/Sites/_sandbox/drupal-project-reviews/mini_blocks/theme/mini_blocks_view_all.tpl.php).
    Warning: Invalid argument supplied for foreach() in include() (line 18 of /Users/joachim/Sites/_sandbox/drupal-project-reviews/mini_blocks/theme/mini_blocks_view_all.tpl.php).

Lastly, I don't think you've really addressed the problem of module duplication. This looks exactly like boxes to me, except that miniblocks don't get exposed to the blocks system. (Which raises the question: why the name 'miniblocks' if they're not usable as blocks?) I would describe this more as a system that lets you have named snippets. Though if the point of the machine ID is portability (which is a good thing, I agree), then you really should consider using CTools to make the actual snippets exportable.

joachim’s picture

Oh, and lastly, there's no sanitizing of the mini block values: so mini_blocks_get_value() returns potentially dangerous output.

EDIT: Ok there is sanitizing of the mini block ID -- but for that you should probably be using the built-in machine_name form element, which does things for you.

<?php print htmlentities(substr($row['mb_value'], 0, 200), ENT_QUOTES)

Similarly, here you should be using the built-in Drupal sanitizing functions such as check_plain().

And you're not sanitizing mini_blocks_get_value(), which is presumably what users would be calling to get the value to output.

joachim’s picture

Searching for 'snippets' found me:

https://www.drupal.org/project/snippet
https://www.drupal.org/project/markup_snippets (D6 only)

That first one looks like it might cover a lot of your functionality and more -- sorry! :/

cfischer83’s picture

Status: Needs work » Needs review

@joachim thanks for the extensive review.

First, let me clarify some things about the similar behavior to some other modules including snippet. When I set out to make this a while back, every other similar module came with a myriad of features that either conflicted with the approach/architecture I wanted (e.g. 'boxes' filling up my blocks) or came with more requirements than I wanted (snippets is a great example: panels is a huge module that is required). This is a case where going to contribute to these other projects wouldn't work because what I'm aiming for is light-weight, no cruft solutions with minimal requirements and that would require removing features from other contributed modules. It comes down to a fundamentally different architecture.

Now for the code pieces:

Don't use a dynamic query here: it's a simple query and it needs to be fast.

Updated to db_query (although a question: will this hurt if something other than MySQL is used?)

Don't use arg() here: pass a parameter in from hook_menu().

Updated to use 'page arguments' in hook_menu

That's not the standard signature for form builder params. It's also good practice to suffix a form builder with _form for clarity.

Updated function names (validate + submit) to suffix _form

There's no need for a fieldset at the top level of the form.

Removed fieldset.

What if I'm editing block foo, and change its key to bar, and bar exists?

This was taken care of in the _validate function, but now that I've implemented your suggestion of using '#machine_name' this is handled automatically, so I removed that section from _validate

Don't use arg() -- instead, set a hidden form value is_new or something -- see how entity forms handle this.

Implemented '#type' => 'value', to hide from browsers

The query string seems weird.
Also, don't use drupal_goto() in a form submit: use the form redirect system.

Changed to the redirect system using $form_state['redirect']

You're updating the date on the block too. Is this then an updated timestamp rather than a created timestamp? Ditto the uid: that's the last user to edit. Both of these are unlike how other things work in Drupal, so worth commenting on to prevent confusion.

Added comment to clarify.

It's not usual at all to use a tpl file for something like a form, especially if all you're doing it printing out the form!
Also, you're repeating the page title, and showing a link to the list page that's pointless because you have the breadcrumb and the tabs.

I completely removed the theme functionality since I could gain it all through hook_menu and forms API.

use theme_table(), not raw HTML

Thanks for this! I've implemented it. I didn't know about this and it makes things much simpler :)

When I install the module and go to the admin page, I get these errors:

I've removed the offending code. Once I finished all my changes, I did a fresh install and went through all the functionality and found no errors in Watchdog logs.

here you should be using the built-in Drupal sanitizing functions such as check_plain().

Implemented check_plain().

klausi’s picture

Status: Needs review » Needs work
Issue tags: -PAReview: review bonus

Thank you for your reviews. When finishing your review comment also set the issue status either to "needs work" (you found some problems with the project) or "reviewed & tested by the community" (you found no major flaws).

manual review:

  1. please add the differences to existing projects to the project page so that user can make an educated choice what module to use.
  2. mini_blocks_schema(): doc block is wrong, this should be documented as hook implementation. See https://www.drupal.org/coding-standards/docs#hookimpl
  3. mini_blocks_schema(): the db_table_exists() call is wrong here, since the schema might get loaded for other purposes.
  4. db_table_exists(): why is the serial id column necessary? Please add a comment.
  5. mini_blocks_load(): instead of the foreach() loop just use ->fetchObject() to get one result row.
  6. mini_blocks_get_value(): what is $block here? The machine name? Please add @param docs, see https://www.drupal.org/coding-standards/docs#param
  7. mini_blocks_admin_add_form_validate(): do not check for required form fields here, use the #required property of the form API in mini_blocks_admin_add_form() instead. See https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.h...
  8. mini_blocks_overview(): "'date' => 'Date',": all user facing text must run through t() for translation, same for the other table headers.
  9. "t('Type in the unique name of a mini block to') . ' ' . $action . ' ' . t('its value'),": don't concatenate variables into translatable strings, use placeholders with t() instead. See https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/t/7
  10. mini_blocks_menu(): 'admin/structure/mini-blocks/edit/%' should be 'admin/structure/mini-blocks/edit/%mini_blocks' so that block object is loaded automatically for you and passed to the page callback. See https://api.drupal.org/api/drupal/modules!system!system.api.php/function...
  11. Project page: "Module always defaults to allow PHP code, so apply permissions with caution.": what does that mean? Where is PHP code allowed? One difficulty with this module is that it never outputs anything and leaves that to the developer - so they need to sanitize the output appropriately. Would be nice to have an example on the project page besides the l() case where check_plain() is done automatically. Something like $output .= filter_xss_admin(mini_blocks_get_value("my_test_block"));

So the project page with the missing similar modules and the misuse of t() with concatenating variables to it (can easily cause XSS security issues) are blockers right now. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

joachim’s picture

> One difficulty with this module is that it never outputs anything and leaves that to the developer - so they need to sanitize the output appropriately.

Oh yes, that reminds me of something I thought of: you might want to consider one of:

- bundling an input format with this module that allows insertion of snippets
- providing snippets as tokens, so that another module that provides a token input format can be used (I'm sure that exists!)

> came with more requirements than I wanted (snippets is a great example: panels is a huge module that is required)

Wow, that's a weird choice they've made there!

I do think you should reconsider the module name though -- miniblocks is very confusing!

cfischer83’s picture

Status: Needs work » Needs review

@ klausi

please add the differences to existing projects to the project page so that user can make an educated choice what module to use.

Added an item to the description.

mini_blocks_schema(): doc block is wrong, this should be documented as hook implementation. See https://www.drupal.org/coding-standards/docs#hookimpl

Updated

mini_blocks_schema(): the db_table_exists() call is wrong here, since the schema might get loaded for other purposes.
db_table_exists():

Removed this. For some reason when I did a module disable and then re-enable I got a strange MySQL error originally, but now that doesn't happen. I'm not sure what the issue was before, but all looks good now.

why is the serial id column necessary? Please add a comment.

Future usage. Added comment.

mini_blocks_load(): instead of the foreach() loop just use ->fetchObject() to get one result row.

Updated.

mini_blocks_get_value(): what is $block here? The machine name? Please add @param docs, see https://www.drupal.org/coding-standards/docs#param

Added comment specifying both from UI and DB perspectives.

mini_blocks_admin_add_form_validate(): do not check for required form fields here, use the #required property of the form API in mini_blocks_admin_add_form() instead. See https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.h...

Thanks. I've implemented and this allowed me to remove the _validate() function completely.

mini_blocks_overview(): "'date' => 'Date',": all user facing text must run through t() for translation, same for the other table headers.

Added t() function.

"t('Type in the unique name of a mini block to') . ' ' . $action . ' ' . t('its value'),": don't concatenate variables into translatable strings, use placeholders with t() instead. See https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/t/7

Updated concatenation to placeholders.

mini_blocks_menu(): 'admin/structure/mini-blocks/edit/%' should be 'admin/structure/mini-blocks/edit/%mini_blocks' so that block object is loaded automatically for you and passed to the page callback. See https://api.drupal.org/api/drupal/modules!system!system.api.php/function...

Nice feature. I didn't know about this. I've updated it to use this.

Project page: "Module always defaults to allow PHP code, so apply permissions with caution.": what does that mean? Where is PHP code allowed? One difficulty with this module is that it never outputs anything and leaves that to the developer - so they need to sanitize the output appropriately. Would be nice to have an example on the project page besides the l() case where check_plain() is done automatically. Something like $output .= filter_xss_admin(mini_blocks_get_value("my_test_block"));

Added your example (as first example) and clarify to sanitize output from the block's value.

@ joachim

I may do an extension in the future the allow this. I'm currently looking at options now.

rajeev_drupal’s picture

Assigned: Unassigned » rajeev_drupal

I am reviewing it..

rajeev_drupal’s picture

Assigned: rajeev_drupal » Unassigned
Issue tags: +#DCM2015

Automated Review

Yes

Manual Review

Individual user account
Yes: Follows the guidelines for individual user accounts.
No duplication
Yes: Does not cause module duplication and/or fragmentation.
Master Branch
Yes: Follows the guidelines for master branch.
Licensing
Yes: Follows the licensing requirements.
3rd party assets/code
Yes: Follows the guidelines for 3rd party assets/code.
README.txt/README.md
Yes: Follows the guidelines for in-project documentation and/or the README Template.
Code long/complex enough for review
Yes: Follows the guidelines for project length and complexity.
Secure code
Yes: Meets the security requirements. / No: List of security issues identified.]
Coding style & Drupal API usage
[List of identified issues in no particular order. Use (*) and (+) to indicate an issue importance. Replace the text below by the issues themselves:
  1. mini_blocks_admin_add_form_submit :
      if ($action == 'edit') {
        // The mb_date and uid is always updated to the new time and uid.
        $mbid = db_update('mini_blocks')
          ->fields(array(
            'mb_id' => $key,
            'mb_value' => $val,
            'uid' => $uid,
            'mb_date' => REQUEST_TIME,
          ))
          ->condition('mb_id', $key_original, '=')
          ->execute();
    
        drupal_set_message(t('Mini Block Edited'));
        $form_state['redirect'] = 'admin/structure/mini-blocks';
      }
      else {
        $mbid = db_insert('mini_blocks')
          ->fields(array('mb_id', 'mb_value', 'uid', 'mb_date'))
          ->values(array(
            'mb_id' => $key,
            'mb_value' => $val,
            'uid' => $uid,
            'mb_date' => REQUEST_TIME,
          ))
          ->execute();
    
        drupal_set_message(t('Mini Block Added'));
        $form_state['redirect'] = 'admin/structure/mini-blocks';
      }

    Use the drupal_write_record it will provide the free validation for you as well.

  2. No configure link in info file
  3. Found no deltion option of the miniblock.Plesae specify ?

The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.

If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.

This review uses the Project Application Review Template.

cfischer83’s picture

@ rajeev_drupal thanks for your review.

1. I've updated to use the drupal_write_record() function here.
2. I've updated to have a configure link in my .info file.
3. This is a feature I plan to add in the near future.

Thanks!

naveenvalecha’s picture

You need another review bonus to that will put you on the high priority list, then git administrators will take a look at your project right away :)

cfischer83’s picture

@ naveenvalecha

I want to make sure that it's solid since I only have one opportunity left for a review bonus. Do you feel it's ready?

naveenvalecha’s picture

Assigned: Unassigned » naveenvalecha
Issue summary: View changes

@cfischer83,
One git admin(@klausi) has done a review and for getting another review bonus from another git admin you need another review bonus.See Project application workflow for more info. https://www.drupal.org/node/532400
corrected git clone command and added automated review link.
Assigned to myself for next review that may be in tonight.

klausi’s picture

@cfischer83: you can get multiple review bonuses, so don't worry ;-)

naveenvalecha’s picture

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

@cfischer83,
First thanks for Contribution! I have not found any release blocker.Congrats setting it to RTBC :)

Automated Review

Best practice issues identified by pareview.sh / drupalcs / coder.

Review of the 7.x-1.x branch (commit 5ac44d7):

Manual Review

Individual user account
Yes: Follows the guidelines for individual user accounts.
No duplication
Yes: Does not cause module duplication and/or fragmentation.
Master Branch
Yes: Follows the guidelines for master branch.
Licensing
Yes: Follows the licensing requirements.
3rd party assets/code
Yes: Follows the guidelines for 3rd party assets/code.
README.txt/README.md
Yes: Follows the guidelines for in-project documentation and/or the README Template.
Code long/complex enough for review
Yes: Follows the guidelines for project length and complexity.
Secure code
Yes: Meets the security requirements.
Coding style & Drupal API usage
[List of identified issues in no particular order. Use (*) and (+) to indicate an issue importance. Replace the text below by the issues themselves:
  1. hook_help() is missing in this module.It would be nice if you add it at the top in .module file.
  2. function mini_blocks_load($block) { : The parameter name should be $mb_id instead of $block because it is referring to machine menu block id.
  3. It would be nice if you also display the Edit link in the mini blocks listing page admin/structure/mini-blocks instead of linking the mb_id field to edit page.
  4. you should also provide the function to delete the menu block.It would be nice if you also display the Delete link in the mini blocks listing page admin/structure/mini-blocks
  5. mini_blocks_sanitize : Usage of single quotes is prefferable than double quotes.Also please add a comment above the regression what it do.
  6. mini_blocks_overview : Usage of single quotes is prefferable than double quotes.Also please add a comment above the regression what it do.
  7. mini_blocks_overview : Use the "db_query is preferrable than db_select for static" queries.
  8. (+)mini_blocks_overview : Implement the pager on this page because its not the right approach to display all the data on this page without pager.
  9. mini_blocks_admin_add_form :
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Save Changes'),
        '#id' => t('edit-submit'),
      );

    Please add a comment about the neeed of #id.

  10. Readme.txt is nice :)
  11. mini_blocks_admin_add_form_submit :
      $record = array(
        'id' => $id,
        'mb_id' => $key,
        'mb_value' => $val,
        'uid' => $uid,
        'mb_date' => REQUEST_TIME,
      );
    
      if ($action == 'edit') {
        $primary_key = 'id';
        $record['id'] = $id;
        $return = drupal_write_record('mini_blocks', $record, $primary_key);
      }
      else {
        $return = drupal_write_record('mini_blocks', $record);
      }

    you can also write it like this.This will remove the dependency of edit action.

      $record = array(
        'mb_id' => $key,
        'mb_value' => $val,
        'uid' => $uid,
        'mb_date' => REQUEST_TIME,
      );
      if (isset($id)) {
        $record['id'] = $id;
        $return = drupal_write_record('mini_blocks', $record, 'id');
      }
      else {
        $return = drupal_write_record('mini_blocks', $record);
      }
  12. mini_blocks_overview : drupal_substr is preffered over substr
  13. mini_blocks_admin_add_form_submit : Remove the return $return; after the $form_state['redirect'] because its not needed here.If it is please add a comment.

The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.

If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.

This review uses the Project Application Review Template.

Please take another review bonus, that will put you on the high priority list, then git administrators will take a look at your project right away :)
Awesome Use of form Api :)

cfischer83’s picture

klausi’s picture

Status: Reviewed & tested by the community » Fixed

Review of the 7.x-1.x branch (commit 5ac44d7):

  • Coder Sniffer has found some issues with your code (please check the Drupal coding standards).
    FILE: /home/klausi/pareview_temp/mini_blocks_forms.inc
    ----------------------------------------------------------------------
    FOUND 1 ERROR AFFECTING 1 LINE
    ----------------------------------------------------------------------
     110 | ERROR | [x] Expected 1 space after FOREACH keyword; 0 found
    ----------------------------------------------------------------------
    PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
    ----------------------------------------------------------------------
    
  • No automated test cases were found, did you consider writing Simpletests or PHPUnit tests? This is not a requirement but encouraged for professional software development.

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. I think the README should also contain a warning about the XSS threat same as on the project page.
  2. mini_blocks_load(): mini_blocks_sanitize() is not needed here, the DB API will sanitize the value automatically in the placeholder.

But that are not application blockers, so ...

Thanks for your contribution, cfischer83!

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.