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
Comment #1
awasson commentedComment #2
paulmckibbenHi 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:
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!
Comment #3
awasson commentedThank you so much for having a look. I'll fix that up and update the status once I have.
Cheers,
Andrew
Comment #4
awasson commentedOk, 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
Comment #5
vineethaw commentedHello,
The line no.52 in the xmlcharts.inc file should be if ($cache == cache_get($token)) instead of if ($cache = cache_get($token)) .
Comment #6
awasson commented@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
Comment #7
peterx commentedI 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.Comment #8
peterx commentedMemory 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.
Comment #9
awasson commented@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
Comment #10
drupal_bn4f commentedHi 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
I am not doing security checks / Drupal API usage checks yet.
This review uses the Project Application Review Template.
Comment #11
awasson commentedUpdate
@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
Comment #12
awasson commentedUpdate
@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
Comment #13
awasson commentedComment #14
awasson commentedComment #15
awasson commentedHi 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)
Comment #16
mpdonadioSorry 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.
Comment #17
awasson commentedNo worries and thanks for looking into my application.
Cheers,
Andrew
Comment #18
mpdonadioAutomated Review
Review of the 7.x-1.x branch (commit b8d4515):
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
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.
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.
Comment #19
peterx commentedI like the simplicity of your approach. Really easy to configure the currency etc.
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.
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. :-)
Comment #20
awasson commented@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
Comment #21
awasson commentedAlso, I've updated Watchdog to use tokens in the .inc and .install files.
Comment #22
yuriy.babenko commented@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.
Comment #23
awasson commentedHi 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.
Comment #24
awasson commentedI've updated time() and replaced with REQUEST_TIME.
Comment #25
pushpinderchauhan commentedAutomated Review
Best practice issues identified by pareview.sh / drupalcs / coder. None
Review of the 7.x-1.x branch (commit 33a2276):
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
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.
Comment #26
pushpinderchauhan commentedThanks 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.
Comment #27
awasson commentedThat 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