Pay with a tweet implements tweet payment feature. This allows the website to
make downloads available to users with a tweet as payment.

Pay with a tweet provides a token and unlimited blocks to show the downloads.

You need to create an application on twitter (https://dev.twitter.com/) with access level "Read and write" to get the values ​​needed for configuration. When creating the application on Twitter, the callback URL is specified in the module configuration screen. (Instructions on project page)

Project link:
https://drupal.org/sandbox/rolando.caldas/2007180

Git clone: git clone --branch 7.x-1.x http://git.drupal.org/sandbox/rolando.caldas/2007180.git pay_with_a_tweet

Drupal version: 7, dependencies: OAuth (https://drupal.org/project/oauth)

Reviews of other projects

https://drupal.org/node/2052349#comment-7697195
https://drupal.org/node/2052217#comment-7697381
https://drupal.org/node/2052201#comment-7697313

https://drupal.org/node/2049679#comment-7703109
https://drupal.org/node/2050019#comment-7703177
https://drupal.org/node/2040297#comment-7703217

https://drupal.org/node/2004572#comment-7709699
https://drupal.org/node/2048779#comment-7709759
https://drupal.org/node/2054613#comment-7709989

Comments

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://ventral.org/pareview/httpgitdrupalorgsandboxrolandocaldas2007180git

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.

PA robot’s picture

Issue summary: View changes

Wrong git clone.

rolando.caldas’s picture

Status: Needs work » Needs review

fixed.

vaibhavjain’s picture

Status: Needs review » Needs work

Some changes you can do.

Library Files
If your Oauth library is not hacked / patched, you can provide the link for it, rather than providing it with the module.
Same goes for twitteroauth library.

Install File
In Hook_install - "variable_del('pay-with-a-tweet');", this should be deleted in hook_uninstall

Module File
Line 162 - "hook_entity_entity_delete", should be hook_entity_delete

Admin INC
Line 135 - "variable_set_value(PAY_WITH_A_TWEET, $settings);" Function definition missing "variable_set_value"

Please check on these.

rolando.caldas’s picture

Status: Needs work » Needs review

Hello,

Install File
In Hook_install - "variable_del('pay-with-a-tweet');", this should be deleted in hook_uninstall

changed!

Module File
Line 162 - "hook_entity_entity_delete", should be hook_entity_delete

changed!

Admin INC
Line 135 - "variable_set_value(PAY_WITH_A_TWEET, $settings);" Function definition missing "variable_set_value"

changed!

Library Files
If your Oauth library is not hacked / patched, you can provide the link for it, rather than providing it with the module.
Same goes for twitteroauth library.

I have deleted the oauth library. Now, Pay with a Tweet has oAuth module as dependency (https://drupal.org/project/oauth).

I have not deleted the file lib/twitteroauth.php. I had to remove the require to oauth library and anothers changes to drupal coding standards

rolando.caldas’s picture

Issue summary: View changes

correct development version git clone

brice_gato’s picture

Status: Needs review » Needs work

Hello rolando.caldas,
In your pay_with_a_tweet.info line 9 : oauth_common module is obsolete (https://drupal.org/project/oauth_common).
use oauth.

rolando.caldas’s picture

Hello brice_gato,

changed oauth_common to oauth

thanks!!

I checked your info. The oauth_common module is obsolte, but the dependency name of oauth module (https://drupal.org/project/oauth) is oauth_common, the oauth doesn't exists. So I revert this change.

You can try installing the module pay_with_a_tweet with oauth dependence to check that it does not work. With dependence oauth_common and oauth module (https://drupal.org/project/oauth) installed, the installation is performed without problem.

rolando.caldas’s picture

Status: Needs work » Needs review

Changed twitter api version to 1.1

webevt’s picture

Status: Needs review » Needs work

Hi

Good idea for a project. Did you think about an integration with commerce and commerce_file module?

Manual review:

  • pay_with_a_tweet_theme(): there is no need for using drupal_get_path() twice (line 116, 121) - you can use $path variable that comes to the hook_theme() as a fourth argument. See hook_theme()
  • pay_with_a_tweet_render(), line 269: I think you can use url() function here.
  • pay_with_a_tweet_twitter_connect(), line 52: there's no need for drupal_exit() here, because drupal_goto() does it for you. The same issues occurs in your several other functions.

Did you think of participating in a review bonus program? This will speed up the processing of your application.

Regards

rolando.caldas’s picture

Status: Needs work » Needs review

Hello WebEvt,

Good idea for a project. Did you think about an integration with commerce and commerce_file module?

Sounds good. Maybe in a future version. I think it's better than the first version do the basics well and that future versions complicate

pay_with_a_tweet_theme(): there is no need for using drupal_get_path() twice (line 116, 121) - you can use $path variable that comes to the hook_theme() as a fourth argument. See hook_theme()

Great! I don't know it. Checked and changed.

pay_with_a_tweet_render(), line 269: I think you can use url() function here.

I have seen that $base_url and url() were necessary.

pay_with_a_tweet_twitter_connect(), line 52: there's no need for drupal_exit() here, because drupal_goto() does it for you. The same issues occurs in your several other functions.

Checked and changes.

Did you think of participating in a review bonus program? This will speed up the processing of your application.

I know and is my pending action :(

Thank you!

Note: With the changes it's necessary clear cache if you already have installed the module

flebrenn’s picture

Category: task » bug
StatusFileSize
new39.8 KB

Hello,

When I want to add pay button with a tweet (admin/pay_with_a_tweet/add) I have notice/error messages (see attached file).
Before, I didn't configured module.
My test:
- title:test
- message: test
- image: jpg image
- Download: jpg image
- I saved this form

Bye,

flebrenn’s picture

StatusFileSize
new15.76 KB
new68.34 KB

#10: If you have this error, please check status_report (admin/reports/status) and change permission for CTools CSS Cache.

After that, I have new errors (see attached files: error and pay_with_a_tweet table). Pay buttons are correctly saved but seems to have an error l.30-32 (pay_with_a_tweet.controller.php save()).

flebrenn’s picture

StatusFileSize
new22.04 KB

New error when I put a pay_button block and I click on picture (see attached file).

flebrenn’s picture

Try this patch to resolve #11.

rolando.caldas’s picture

Hello flebrenn,

thanks for your testing!!

I applied your patch.

I checked your #12 message.

There is a problem with the session that happens when twitter not redirect to callback url. It's a punctual error but can be regular when in dev.twitter.com you have not configured the callback value

I've checked it and I added a error message when this problem appears.

gauravjeet’s picture

Status: Needs review » Needs work

Hi,
This is a nice module with an extensive work done. Manual review is as follows -

.module file line 333, 338
-You can use require_once() instead of module_load_include()

.install file
- Not all variables have been deleted - pay_with_a_tweet_download, anonymous

.admin.inc file line 31
- wrong usage of t() function, use placeholders instead that would be helpful in translation.
Instead of :
$table['empty'] = t('There are no downloads available.') . ' ' . l(t('Create a download'), 'admin/pay_with_a_tweet/add');
you can use :
$table['empty'] = t('There are no downloads available. !create', array('!create' => l('Create a download'), 'admin/pay_with_a_tweet/add'));

.admin.inc file line 33
- please use addTag('node_access') to avoid a security risk. There are some nodes which have restricted access, not using addTag() in the query would bypass them

.admin.inc file line 138
- is there really need for intval() ? This is really a 'no problem' but still it's of no use because a checkbox in form API either returns a 0 or a 1.

INSTALL.txt file
- There is no need to include an extra descriptive file, you can add this description in README.txt itself

rolando.caldas’s picture

Status: Needs work » Needs review

Hi gauravjeet_singh,

thanks a lot for your comments!!

.module file line 333, 338
-You can use require_once() instead of module_load_include()

I had used module_load_include for use the drupal api and include the files with their absolute route. I checked another projects (like coder) and it uses the require_once when the file to include is in the same module. So I changed this lines to:

/**
 * include the block functions file
 */
require_once realpath(__DIR__) . '/pay_with_a_tweet.blocks.inc';

/**
 * include the tokens functions file
 */
require_once realpath(__DIR__) . '/pay_with_a_tweet.tokens.inc';
.install file
- Not all variables have been deleted - pay_with_a_tweet_download, anonymous

The pay_with_a_tweet_download and pay_with_a_tweet_image variables doesn't exist. So It's not necesary delete it. But this variables can't be configured so I removed it from the code (.admin.inc file lines 215 and 223).

The variable anonymous is a drupal core variable. This variable is set when you change the name for anonymous users in http://www.example.com/admin/config/people/accounts. So I can't remove this variable in the uninstall hook ;)

.admin.inc file line 31
- wrong usage of t() function, use placeholders instead that would be helpful in translation.
Instead of :
$table['empty'] = t('There are no downloads available.') . ' ' . l(t('Create a download'), 'admin/pay_with_a_tweet/add');
you can use :
$table['empty'] = t('There are no downloads available. !create', array('!create' => l('Create a download'), 'admin/pay_with_a_tweet/add'));

changed!

.admin.inc file line 33
- please use addTag('node_access') to avoid a security risk. There are some nodes which have restricted access, not using addTag() in the query would bypass them

I don't use addTage('node_access') because the query doesn't call to node data. Pay_with_a_tweet is an own entity (like nodes, taxonomies, users, ...) and doesn't exist any restricted access to the pay_with_a_tweet entity content.

.admin.inc file line 138
- is there really need for intval() ? This is really a 'no problem' but still it's of no use because a checkbox in form API either returns a 0 or a 1.

Yes, the intval isn't necesary. I remove it.

INSTALL.txt file
- There is no need to include an extra descriptive file, you can add this description in README.txt itself

done!

rolando.caldas’s picture

Issue summary: View changes

New dependency: OAuth (https://drupal.org/project/oauth)

swim’s picture

Status: Needs review » Needs work

Hey Rolando,

just a quick one but I notice your hook_menu uses the access arg create pay_with_a_tweet however I can't see this defined in your hook permissions. Your also including module_load_include('php', 'oauth_common', 'lib/OAuth'); at the top of your .module file, unless your using this somewhere else I missed you should only need to include it inside the functions implementing it; which looks like both in pay_with_a_tweet.page.inc. As such;

/**
 * Menu callback. Connect to Twitter to grant access to publish tweet.
 * 
 * @global $base_url
 * 
 * @param object $pay_with_a_tweet
 *   The pay_with_a_tweet entity to use.
 */
function pay_with_a_tweet_twitter_connect($pay_with_a_tweet) {
  module_load_include('php', 'oauth_common', 'lib/OAuth');

Your comments in pay_with_a_tweet.page.inc are in an odd format, please checkout the in-line code comments section.

Thanks,

rolando.caldas’s picture

Status: Needs work » Needs review

Hello hapax legomenon,

Your comments are correct!!

  • I changed in hook_menu the access arg "create pay_with_a_tweet" to "administer pay_with_a_tweet".
  • In .module I removed module_load_include('php', 'oauth_common', 'lib/OAuth'); and I put it on this .pages.inc functions: pay_with_a_tweet_twitter_connect and pay_with_a_tweet_twitter_callback
  • In .pages.inc I updated the code comments to inline-comment (the comments inside functions)

thanks!

klausi’s picture

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

manual review:

  1. pay_with_a_tweet_uninstall(): Do not use db_select() for simple static queries, use db_query() instead. See http://drupal.org/node/310075 . Same in pay_with_a_tweet_get_all().
  2. pay_with_a_tweet_entity_delete(): this looks wrong, because this hook will fire on deletion of any entity. So if i have a profile2 entity with a pid this iwll delete some arbitrary pay_with_a_tweet entuity. Why do you even need this hook? Please add a comment.
  3. pay_with_a_tweet_save(): the "&" is useless.
  4. pay_with_a_tweet_block_save(): The check_plain() calls are wrong here. "When handling data, the golden rule is to store exactly what the user typed. When a user edits a post they created earlier, the form should contain the same things as it did when they first submitted it. This means that conversions are performed when content is output, not when saved to the database". See https://drupal.org/node/28984
  5. PayWithATweetController: why do you need your own controller class and cannot use the DrupalDefaultEntityController? Please add a comment.
  6. pay_with_a_tweet_render(): this looks like a preprocess function - so you should implement a theme preprocess hook so that this called automatically whenever the theme function is invoked.
  7. pay_with_a_tweet_edit(): this can be removed, just use drupal_get_form as page callback in hook_menu() directly.
  8. pay_with_a_tweet_info(): this is where the check_plain() class on title and message should happen, not in pay_with_a_tweet_form_submit().
  9. pay_with_a_tweet_info(): duplication of Views? You can list entities already with Views and the Entity API module.

The correct usage of check_plain() is a blocker. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

rolando.caldas’s picture

Status: Needs work » Needs review

Hello klausi,

Thanks for your comments. You make me work! ;)

pay_with_a_tweet_uninstall(): Do not use db_select() for simple static queries, use db_query() instead. See http://drupal.org/node/310075 . Same in pay_with_a_tweet_get_all().

fixed!

pay_with_a_tweet_entity_delete(): this looks wrong, because this hook will fire on deletion of any entity. So if i have a profile2 entity with a pid this iwll delete some arbitrary pay_with_a_tweet entuity. Why do you even need this hook? Please add a comment.

You are right. It's my fault. I don't want use hook_entity_delete. I changed the name to pay_with_a_tweet_delete because the function will be called when you confirm deleted a pay_with_a_tweet button.

pay_with_a_tweet_save(): the "&" is useless.

fixed!

pay_with_a_tweet_block_save(): The check_plain() calls are wrong here. "When handling data, the golden rule is to store exactly what the user typed. When a user edits a post they created earlier, the form should contain the same things as it did when they first submitted it. This means that conversions are performed when content is output, not when saved to the database". See https://drupal.org/node/28984

Changed! I apply this comment to all check_plain

PayWithATweetController: why do you need your own controller class and cannot use the DrupalDefaultEntityController? Please add a comment.

You are right. I don't need my own controller. I changed the entity to use the DrupalDefaultEntityController and refactor functions pay_with_a_tweet_save and pay_with_a_tweet_delete to save/delete the entity without the PayWithATweetController.

pay_with_a_tweet_render(): this looks like a preprocess function - so you should implement a theme preprocess hook so that this called automatically whenever the theme function is invoked.

I didn't know this hook. Implemented!!

pay_with_a_tweet_edit(): this can be removed, just use drupal_get_form as page callback in hook_menu() directly.

Fixed. Applied to another functions that do the same.

pay_with_a_tweet_info(): this is where the check_plain() class on title and message should happen, not in pay_with_a_tweet_form_submit().

fixed!

pay_with_a_tweet_info(): duplication of Views? You can list entities already with Views and the Entity API module.

I try to explain me. I did it so because I think that is excessive to force install entity API or views for a single screen. The module has the oauth module like dependency because is really required, but the use of views or entity api to a screen that lists the buttons created does not seem reason enough to force other dependencies. In future versions is a good idea use views and entity api when this modules are installed (but not like dependency), I hope that now the pay_with_a_tweet_info is not a problem.

Thanks!

rolando.caldas’s picture

Issue summary: View changes

Add reviews of other projects

klausi’s picture

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

manual review:

  1. "'%title' => check_plain($pay_with_a_tweet->title) . ' [' . $pay_with_a_tweet->pid . ']',": no need to run check_plain() here since the "%" placeholder will sanitize the variable for you already. And double escaping is bad. Also elsewhere.
  2. twitteroauth.php: appears to be 3rd party code. 3rd party code is not generally allowed on Drupal.org and should be deleted. This policy is described in the getting involved handbook. It also appears in the terms and conditions you agreed to when you signed up for Git access, which you may want to re-read, to be sure you're not violating other terms. The Libraries API module is a recommended method for adding 3rd party dependencies without directly including the code on Drupal.org.
  3. pay_with_a_tweet_delete_form(): If a form has a submit function, then hidden form values are not needed. Instead, any values that you need to pass to $form_state['values'] can be declared in the $form array as '#type' => 'value'. Also elsewhere.

Otherwise looks almost ready, the 3rd party code is a blocker. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

rolando.caldas’s picture

Status: Needs work » Needs review

Hello klausi,

First at all, thanks you! I learned a lot with your messages.

"'%title' => check_plain($pay_with_a_tweet->title) . ' [' . $pay_with_a_tweet->pid . ']',": no need to run check_plain() here since the "%" placeholder will sanitize the variable for you already. And double escaping is bad. Also elsewhere.

I removed the check_plain when I use the "%" placeholder.

pay_with_a_tweet_delete_form(): If a form has a submit function, then hidden form values are not needed. Instead, any values that you need to pass to $form_state['values'] can be declared in the $form array as '#type' => 'value'. Also elsewhere.

I didn't know that. Changed and working fine!

twitteroauth.php: appears to be 3rd party code. 3rd party code is not generally allowed on Drupal.org and should be deleted. This policy is described in the getting involved handbook. It also appears in the terms and conditions you agreed to when you signed up for Git access, which you may want to re-read, to be sure you're not violating other terms. The Libraries API module is a recommended method for adding 3rd party dependencies without directly including the code on Drupal.org.

Sorry. Yes I read the sections that you show me before programming the module. But I understood that the not inclusion of third-party code was more a suggestion than an obligation. Clearly I was wrong for what I have already corrected the error.

I deleted the code and created my own class to take the necessary actions (getting permission to post to twitter and posting a tweet) and only those.

So, I hope that with these changes, the module is as it should be.

Thanks a lot!

rolando.caldas’s picture

Issue summary: View changes

add new reviews of other projects

rolando.caldas’s picture

Hello

I fix a bug in hook_uninstall (it generated a notice) and add {} to the table name in the db_select() (in hook_uninstall and pay_with_a_tweet_get_all()

thanks!

klausi’s picture

Assigned: Unassigned » cweagans
Status: Needs review » Reviewed & tested by the community
Issue tags: -PAreview: review bonus

manual review:

  1. Well, instead of providing your own oauth library class you could just tell people where they should download the lib in the installation instructions. That way you avoid duplicating code that now has to be maintained twice.
  2. "require_once realpath(__DIR__) . '/pay_with_a_tweet.blocks.inc';": note that __DIR__ will only work on PHP 5.3, so you should add a dependency on PHP 5.3 to your info file (Drupal 7 requires only PHP 5.2.).

But otherwise looks RTBC to me. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

Assigning to cweagans as he might have time to take a final look at this.

cweagans’s picture

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

I'd also encourage you to just tell people where to download the third party code, and perhaps use http://drupal.org/project/libraries to manage that dependency.

For this bit:

 389 /**
 390  * include the block functions file
 391  */
 392 require_once realpath(__DIR__) . '/pay_with_a_tweet.blocks.inc';
 393 
 394 /**
 395  * include the tokens functions file
 396  */
 397 require_once realpath(__DIR__) . '/pay_with_a_tweet.tokens.inc';

1) To load module include files, you should use module_load_include; and
2) If you're including this unconditionally, there's no reason to split them out into another file. It is, in fact, a bit slower, since you're adding a couple of disk reads/file open operations into the mix. You could probably just copy the contents of those files into your .module file and you'd be fine.

Thanks for your contribution, rolando.caldas!

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.

Status: Fixed » Closed (fixed)

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

Anonymous’s picture

Issue summary: View changes

add project reviews