XMLCharts is a Drupal module that consumes, caches and produces blocks to display industrial and precious metal prices from the XML Charts free XML price feeds. If you're looking for a method to place precious and/or industrial metal pricing on your Drupal website, this is probably the solution you're looking for.

Note from awasson: I've finally got a module that I think is worthy to publish to the Drupal-sphere. I'll get my review bonus going in the next few days. I just wanted to get this in the queue while I had the time to do so. I built it because I couldn't find anything like it. I hope others find it useful too.

The XMLCharts Project Page: https://www.drupal.org/sandbox/awasson/2485257

git clone --branch 7.x-1.x http://git.drupal.org/sandbox/awasson/2485257.git xmlcharts
cd xmlcharts

Pareview results page: http://pareview.sh/pareview/httpgitdrupalorgsandboxawasson2485257git

Recent reviews of other projects

[D7] CiviCRM contact distance search
https://www.drupal.org/node/2498413#comment-10043008

[D7] Special Taxonomy Tagging In Body
https://www.drupal.org/node/2487854#comment-10043318

[D7] Views Floorplan
https://www.drupal.org/node/2429983#comment-10044476

[D7] Data Manipulate UI
https://www.drupal.org/node/2492195#comment-9955101
https://www.drupal.org/node/2492195#comment-9955391

Past reviews of other project

[D7] Age Verification Module
https://www.drupal.org/node/2013591#comment-8357369
https://www.drupal.org/node/2013591#comment-8367109
https://www.drupal.org/node/2013591#comment-8368619
https://www.drupal.org/node/2013591#comment-8370081
https://www.drupal.org/node/2013591#comment-8370649

[D7] I18n Menu Admin
https://www.drupal.org/node/2169597#comment-8365767
https://www.drupal.org/node/2169597#comment-8370231
https://www.drupal.org/node/2169597#comment-8379003
https://www.drupal.org/node/2169597#comment-8383617
https://www.drupal.org/node/2169597#comment-8393657
https://www.drupal.org/node/2169597#comment-8463657

Comments

awasson’s picture

Title: XMLCharts - Industrial and Precious Metals Prices » [D7] XMLCharts - Industrial and Precious Metals Prices
Issue summary: View changes
paulmckibben’s picture

Status: Needs review » Needs work

Hi there,
I took a quick look at your module code, and I have a few comments.

General: the comments describing functions/methods need more detail. See https://www.drupal.org/node/1354#functions, under the heading "API documentation standards for functions." Guidelines include:

  • Each parameter of a function must be documented with a @param tag.
  • If a function has a return value, it must be documented with a @return tag.

It does say that if a function is easily described in a single sentence, you may omit the @param and @return tags, but in this case, most of your function comments just repeat the function/method name. A little more description would be helpful.
Also, for xmlcharts.module, the documentation of your hook implementations is fine--no need to change those. Most of the functions that need additional documentation are in xmlcharts.inc, with just a few non-hook functions in xmlcharts.module needing additional documentation.

I installed the module and played with the blocks, and overall it looks great. Just fix those comments and I think this will be good to go!

awasson’s picture

Thank you so much for having a look. I'll fix that up and update the status once I have.

Cheers,
Andrew

awasson’s picture

Status: Needs work » Needs review

Ok, I've gone through the module's inc file and documented the class methods and I've also documented the custom check_time() function for completeness.

Cheers,
Andrew

vineethaw’s picture

Status: Needs review » Needs work

Hello,

The line no.52 in the xmlcharts.inc file should be if ($cache == cache_get($token)) instead of if ($cache = cache_get($token)) .

awasson’s picture

Status: Needs work » Needs review

@vineethaw thanks for reviewing my code.

That isn't an error; that is a conditional of assignment, not equality. It was designed to be written that way.

Changed back to needs review.

Thanks again.

Cheers,
Andrew

peterx’s picture

I tested your blocks in the footer of http://02g.org/. They work. I tested the removal of the link from the first block and it worked. I suggest you add rel="nofollow" for Google. This would be the one change to the code I would require before using the code on a non demo site.

peterx’s picture

Memory usage suggestion. Based on working on sites with hundreds of little modules loaded, reducing memory for regular page loads is a priority.

The .module file contains a chuck of cron code that is used once per hour or less. The code could be moved out to a class or separate file with only a short wrapper function in the .module file. xmlcharts_check_time() would move with the cron code.

awasson’s picture

@peterx: Thanks for dropping by and checking it out. I really appreciate that.

#7 - Great idea. That hadn't occurred to but I will add that to the code and update shortly.

#8 - If I can reduce the memory footprint all the better.

At the moment when cron runs, it checks whether it is the appropriate window to update the cache and if so, then it acquires the XML/JSON object and replaces the caches. I run it once an hour on my demo and every 20 minutes on a production site. I don't know if I can make the code run any more efficiently but I'm happy to do so if you can advise me.

If I move the code into a wrapper function xmlcharts_check_time() it will make the xmlcharts_cron() easier on the eyes but do you have concerns regarding the memory footprint when Cron is called?

So, to summarize, I'll be updating the following:

1) Adding rel="nofollow" to the links.

2) Create wrapper wrapper function xmlcharts_check_time() that runs at xmlcharts_cron().

Thanks for looking at the module and I'll change the status once I'm done.

Cheers,
Andrew

drupal_bn4f’s picture

Hi Andrew,

I also looked at your code here and here is summary of review.

Maybe, you could use more standard titles with your README first file.
Some screen captures could be also nice for any new users.

This is useful module for society for sure.

Regards,
Jouni

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
[No: Does not follow] 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.

I am not doing security checks / Drupal API usage checks yet.

This review uses the Project Application Review Template.

awasson’s picture

Update

@drupal_bn4f: Thanks for having a look at my module. I've updated the README.txt file according to the suggestions at: https://www.drupal.org/node/2181737

@peterx: I've added rel="nofollow" to the links. I'll add the cron wrapper and move xmlcharts_check_time() into the inc file over the weekend when I have a moment.

Thanks to both of you for reviewing my code and providing solid suggestions.

Cheers,
Andrew

awasson’s picture

Update

@peterx: I've moved xmlcharts_check_time() to the inc file and I've added two additional functions to clean up xmlcharts_cron().

xmlcharts_cron() is used to check the GMT time to see when it's appropriate to check the cache for refreshing. At the appropriate time, it calls xmlcharts_check_refresh() and passes the time value of '10:30:00 GMT' or '15:00:00 GMT' depending on the current time.

xmlcharts_check_refresh() creates an instance of the XMLChartsData() object and passes it with the time and type of metal to a helper that checks and refreshes the cache as appropriate.

I tested it overnight and it worked like a charm but I've refined it just that much more today so I'll check it again over the next 24 hours and if anything goes sideways when it is supposed to check and refresh, I'll get on it.

Cheers,
Andrew

awasson’s picture

Issue summary: View changes
awasson’s picture

Issue summary: View changes
awasson’s picture

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

Hi Guys,
I've updated my project application with my Review bonus. I've added some recent ones as well as some that I've done in the past. Please take a moment to give my project another once over and if it's ready for prime time, can you set it to Reviewed By the Community to get the powers that be to give it a look over?

Thanks,
Andrew Wasson (awasson)

mpdonadio’s picture

Assigned: Unassigned » mpdonadio

Sorry for the delay with this. The review admins are pretty backed up with applications. This is next up for me, and I will have it done today or tomorrow.

awasson’s picture

No worries and thanks for looking into my application.

Cheers,
Andrew

mpdonadio’s picture

Assigned: mpdonadio » Unassigned
Status: Needs review » Needs work
Issue tags: +PAreview: security

Automated Review

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

  • 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

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 / No: Does not follow 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

This is a touch judgement call, but we have held others to this standard. You are outputting the data from the webservice unsanitized. Since it is third-party data, it is considered unsafe. xmlcharts_block_view()
should be using t() w/ placeholders and drupal_attributes() at a minimum to sanitize this. This is a security problem, yet a pretty remote one.

Coding style & Drupal API usage

You can use drupal_json_decode() instead of json_decode().

XMLChartsData::xmlMetalsObject(), use placeholders with watchdog(). My trace is that this is not exploitable. Also elsewhere. See https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/watc...

Use REQUEST_TIME instead of time() directly.

xmlcharts_uninstall(), doing wildcard deletion of variables isn't the best idea, as you may accidentally zap another module's variables by accident. It is best to track your own and call varianle_del() multiple times.

xmlcharts may not be the best namespace, considering this is not a generic module for xmlcharts, but one specifically for the precious metals market.

The variable_set() in xmlcharts_block_view() may not be the best idea as this will have performance impacts. I thin kyou can just rely on default values from variable_get() here.

xmlcharts_block_view(), build up render array and not #markup. Also consider a theme function.

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.

(*) Sanitization needed xmlcharts_block_view is the only blocking issue.

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.

peterx’s picture

I like the simplicity of your approach. Really easy to configure the currency etc.

XMLChartsData::xmlMetalsObject(), use placeholders with watchdog()

This becomes relevant if someone extends XMLcharts to produce their own display, perhaps data from another source, or to use the agrarian feed, or you change code to discover the tokens from the source.

Since it is third-party data, it is considered unsafe.

I have had third parties do stupid things with data. Plus their site may have an exposure where their data can be compromised.

The XMLCharts module name is a bit generic. They list a few feeds:
http://www.xmlcharts.com/precious-metals.html Precious Metals XML Price Feed
http://www.xmlcharts.com/agrarian.html Agrarian XML Price Feed

XMLCharts Precious Metals could be a better name. Or you could advertise your development expertise to add other feeds from XMLCharts.com. XMLCharts.com might pay you to expand your code.

In the readme and on the project page, after the current introduction, you could mention that XMLCharts.com has other feeds and subscription services. Someone searching for a way to get an agrarian or energy feed can find your module from a google search.

After the module is published, approach XMLCharts to add a link to your module on their page. The link might convince a Web developer to use Drupal instead of Wordpress for their metals site. :-)

awasson’s picture

Status: Needs work » Needs review

@mpdonadio: Wow! Thanks for such a thorough review! That will be my boilerplate for future reviews that I undertake myself. There is a lot to think about there and I've spent that past two days going through it and considering how to approach it. In response I've updated the following:

1) I've updated xmlcharts_block_view() to use the t() function and the drupal_attributes() functions. I think it probably is overkill but it wasn't a huge undertaking and it negates the security issue and provides the strings as translatable content. How cool is that! I could have cut some corners to avoid using drupal_attributes() since it's all static but what the heck. I was in there so why not go all out.

2) I've updated the inc file to use drupal_json_decode() instead of json_decode(). That was another case of, why not.

3) I've changed the name from XML Charts to "XMLCharts - Industrial and Precious Metals Prices". I've been waffling on the name since day one and since both you and PeterX have mentioned it, I figured I should make the change.

I'm still looking at the other recommendations but I wanted to get the release blocker dealt with as soon as possible. Thanks again for the level of detail in your review. That was awesome!

@peterx: Thanks for giving my module application another review. I really appreciate that. I contacted the folks who make the feed available when I built the first iteration of the module just to make sure they were cool with it (they were) and I will definitely as them if they would like to link to my project page when it's a full fledged project. I'm pretty happy with the module and it's definitely benefitted from the input of the vetting process. Thanks again.

Cheers,
Andrew

awasson’s picture

Also, I've updated Watchdog to use tokens in the .inc and .install files.

yuriy.babenko’s picture

@awasson - I just had a very quick scan through the codebase (haven't installed/used the module yet). One thing that instantly stood out is markup being passed to the translate ( t() ) function throughout the .module file (ex. line 226, 297, 313, etc.). The t() function is meant to translate text, and shouldn't be receiving markup at all. Ideally, all markup should be ran through theming functions and rendered with theme(), but for very small pieces of markup you can get away with hardcoding it.

awasson’s picture

Hi Yuriy,
Thanks for having a look. How's that Vancouver weather feeling to you. Except for today, I'm finding it too hot for even motorbike rides these days. Doesn't stop me though!

Regarding strings, t() and markup, according to the handbook and according to the page on "Dynamic or static links and HTML in translatable strings" (https://www.drupal.org/node/322774), the preferred practice is to enclose the entire string, markup and all in t() and include the necessary tokens for dynamic content. See this, which refers to the above info: https://api.drupal.org/comment/44238#comment-44238 That's pretty much exactly what I've done with mine.

I spent some time reviewing the handbook so if it's incorrect maybe someone can weigh in and we can update it (and I'll make the appropriate changes in my code).

Thanks a gain Yuriy and one of these days we'll have to meet up for coffee on the bikes. I still have my vintage GSXR.

awasson’s picture

I've updated time() and replaced with REQUEST_TIME.

pushpinderchauhan’s picture

Status: Needs review » Reviewed & tested by the community

Automated Review

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

Review of the 7.x-1.x branch (commit 33a2276):

  • 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

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: Follow 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: Meet the security requirements.
Coding style & Drupal API usage

It is always better to take out HTML from t() function. Also, considering using theme_html_tag() instead of writing direct html tag.

But that are not critical application blocker, otherwise I think this is RTBC.

pushpinderchauhan’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for your contribution, Andrew Wasson (awasson)!

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.

awasson’s picture

That is awesome! Thanks everyone for helping me through the vetting process. The module and my knowledge of the Drupal API is all that much better for it.

Cheers,
Andrew

Status: Fixed » Closed (fixed)

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