CVS edit link for fuzzy76

I am a web developer at the norwegian National Centre for integrated care and Telemedicine. We are building an eLearning platform using Drupal, and will be making several modules for Drupal in order to accomplish this.

Our first module is called Certify and integrates with the Quiz module (v4 only) to issue PDF certificates to students upon completion of quizzes. It does this using the command line tool pdftk to fill out a PDF form and saves the resulting file as a "flattened" PDF file.

It is available for download at http://dl.dropbox.com/u/164558/certify.zip and is very close to completion as far as I can tell (a few fixes in the Quiz module is required for the last issues to be ironed out).

As you understand, this module is only the first of several from us, so I will hopefully be able to add a lot of value to the Drupal community in the future. :)

CommentFileSizeAuthor
#13 certify.zip577.33 KBfuzzy76
#7 certify.zip579.62 KBfuzzy76
#2 certify.zip576.31 KBfuzzy76

Comments

fuzzy76’s picture

Status: Postponed (maintainer needs more info) » Needs review
fuzzy76’s picture

StatusFileSize
new576.31 KB
avpaderno’s picture

Status: Needs review » Needs work
Issue tags: +Module review

Hello, and thanks for applying for a CVS account. I am adding the review tags, and some volunteers will review your code, pointing out what needs to be changed.

As per http://drupal.org/cvs-application/requirements, the motivation message should be expanded to contain more details about the features of the proposed module/theme; for modules it should include also a comparison with the existing solutions, while for themes a screenshot is also required.

fuzzy76’s picture

Expansion on the module:

The module named "certify" let you create a certificate (a content type) based on selected quizzes from the Quiz module. These quizzes all have to be completed for the certificate to be awarded. You can also attach a certificate template to the certificate. This is a PDF form file with fields (documented in README.txt). This template is optional, since the module comes with a plain default template.

The users get a progress report (in percent, available in a block) on how much of the certificate they have achieved. When the progress reaches 100%, they are able to download a PDF certificate.

The PDF certificate is generated by using the tool pdftk on the server to fill in the form and flatten the file back to a standard PDF file. These files are cached on the server. The certificate is generated on demand, and not immediately upon completion or in a cronjob. The certificates are stored in a private path to ensure that users cannot view eachothers certificates (or the template file for the certificate).

The module does a comprehensive version check to ensure that the Quiz module is of the version needed. It also does thorough checks on the certificate data directory and path to the pdftk executable and reports any errors found on the status page. It also has help hooks were applicable.

The module comes with a README.txt file that describes requirements, installation and basic use. I have tried to follow all guidelines I could find on drupal.org, and the module has been checked with the Coder module and all PHP notices enabled. As far as I can tell, all strings in the module are also translatable.

There are a few norwegian comment blocks in the code, but since these are used for describing the incompatibilities with different revisions of quizzes, these comments will be removed before a v1.0 release. The Quiz module already has added the necessary hooks on trunk, so this should actually be fixed very shortly.

avpaderno’s picture

Status: Needs work » Needs review

Thanks for your reply.

fuzzy76’s picture

Status: Needs review » Needs work

Due to some changes on trunk in the quiz module, certify no longer works. Will change status back as soon as I've updated the code.

fuzzy76’s picture

Status: Needs work » Needs review
StatusFileSize
new579.62 KB

New version, compatible to latest checkout of 6.x-4.x-dev version of quiz. Several bugfixes. Not version aware yet.

The Macports version of pdftk on OS X has major issues with certificate generation. But several tests on Linux (Ubuntu and Red Hat) worked like a charm.

mogilews’s picture

Having trouble getting this working on Drupal 6.1.4 on XAMPP for Windows Version 1.7.1.

I think there is something wrong with the way I am writing the path. I tried using double \ ("\\" for directory levels) as well and had the same error.

Certify Module Config:

Enter the path to the location where to store certificates.:
C:\xampp\htdocs\certificates
Path to pdftk.:
C:\xampp\htdocs\CMS\helperapps\pdftk.exe

Error log follows:

Execution of pdftk failed - not installed or wrong path?
Command line:
C:\xampp\htdocs\CMS\helperapps\pdftk.exe C:\xampp\htdocs\CMS\modules\certify\default_certificate.pdf fill_form C:\xampp\htdocs\certificates\cert_35_.fdf output C:\xampp\htdocs\certificates\cert_35_.pdf flatten 2>&1
Output:
Unhandled Java Exception: java.io.CharConversionException at 0x0056175e (Unknown Source) at 0x00561c52 (Unknown Source) at 0x00561d03 (Unknown Source) at 0x0057692d (Unknown Source) at 0x0055f64d (Unknown Source) at 0x006bc0ad (Unknown Source) at 0x006994e0 (Unknown Source) at 0x00567a96 (Unknown Source) at 0x0056e8f2 (Unknown Source) at 0x0056e92c (Unknown Source) at 0x00445fa6 (Unknown Source) at 0x0048b15e (Unknown Source) at 0x0048b5b8 (Unknown Source) at 0x0048c238 (Unknown Source) at 0x0046c81f (Unknown Source) at 0x00469301 (Unknown Source) at 0x00466810 (Unknown Source)

fuzzy76’s picture

The "Command line" part of the error log is the actual command line it tries to execute, and it actually looks fine as far as I can tell (though I seldom use Windows). The last element in the line might is POSIX-dependant, but I think Windows should ignore it.

The error looks to be the same error I got when I tried to run it on a Mac using the pdftk executable from Macports. Which as far as I could figure out was due to bad character set support in GCJ which was used for compiling pdftk from Java to an executable. Atleast the error indicates that the files involved probably was loaded ok, but couldn't be parsed for some reason.

Do you have any other pdftk ports for Windows you could try? I can test it under Windows myself, but I am on vacation right now and won't have time for that until august.

mogilews’s picture

I am using the windows executable from http://www.pdfhacks.com/pdftk/pdftk-1.41.exe.zip

I also tested it standalone (outside Drupal/Quiz) in the command line and got the same error

Unhandled Java Exception
java.io.CharConversionException

I saw that this had similar issues in Ubuntu 9.10 until patched, the GCJ environment was mentioned as a culprit there also.

Not sure where I can get another windows port for the current version.

Tried historical release PDFTK 1.12 Windows EXE from http://www.accesspdf.com/pdftk/#history, got the following when testing the EXE as a standalone app:

Error: Failed to open FDF (data) file:
xxx.fdf
No output created

avpaderno’s picture

The purpose of a CVS application is not to debug the code, but to verify if the code doesn't have security issues, follows the coding standards, and uses the correct Drupal functions (and API).

While debugging information could be interesting for fuzzy76, a CVS application is not the issue queue for the module.

avpaderno’s picture

Status: Needs review » Needs work
  • The points reported in this review are not in order or importance / relevance.
  • Most of the times I report the code that present an issue. In such cases, the same error can be present in other parts of the code; the fact I don't report the same issue more than once doesn't mean the same issue is not present in different places.
  • Not all the reported points are application blockers; some of the points I report are simple suggestions to who applies for a CVS account. For a list of what is considered a blocker for the application approval, see CVS applications review, what to expect. Keep in mind the list is still under construction, and can be changed to adapt it to what has been found out during code review, or to make the list clearer to who applies for a CVS account.
  1.   $t = get_t();
      $requirements = array();
      $quizneeded = array('title' => $t('Certify require Quiz v4'), 'description' => $t('Quiz v4 or higher is required'), 'severity' => REQUIREMENT_ERROR);
    
      if ($phase=="runtime" || $phase=="install") {
    
        // Get current list of modules
        $files = drupal_system_listing('\.module$', 'modules', 'name', 0);
    
        if (!isset($files['quiz'])) { // Do we have a quiz module at all? This shouldn't be an issue since the .info specifies it as a dependency
          $requirements['quizneeded'] = $quizneeded;
        }
        else {
    
    

    The dependency from a module is already checked from Drupal; there is no need to write extra code for that.

  2. See http://drupal.org/coding-standards to understand how a module should be written. In particular, see how the code should be formatted; how Drupal variables, global variables, constants, and functions defined from the module should be named.
  3.     'site_name'         => variable_get('site_name', ''),
    
    

    The default value for that Drupal variable is 'Drupal'.

  4.     header('Content-Description: File Transfer');
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment; filename="' . basename($filebase . 'pdf') . '"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($filebase . 'pdf'));
    
    

    The function to use is drupal_set_header().

  5.     watchdog("fail", "Execution of pdftk failed - not installed or wrong path?<br />Command line:<br />%exe<br />Output:<br />%output", array('%exe' => $exec, '%output' => $output), WATCHDOG_ERROR);
        drupal_set_message(t("The certificate generation failed. Please contact a system administrator for assistance."), 'error');
        drupal_goto('/certify');
    
    

    The first parameter of watchdog() is a string that identifies the module that output the message error; 'fail' doesn't identify the module that output the error message.

  6.   //  TODO_1: Utvid funksjonalitete under til å ta høyde for følgende scenario:
      //  Sett at vi har et scenario der det finnes et sertifikat som inneholder to tester og en bruker har tatt en av testene.
      //  For å kunne regne ut riktig prosentscore for brukeren trengs det info også om de quiz'ene som brukeren ikke har besvart.
      //  quiz_get_score_data funksjonen returnerer i dag info om quiz som brukeren har tatt.
      //  Kunne denne funksjonen også sendt de quiz'ene som ikke er besvart, men på en eller annen måte merket de?
      //
      //  Slik koden foreligger nå vil det bli en feil i utregning av progress for et sertifikat fordi quiz'er som brukeren ikke
      //  har besvart ikke tas med i beregningen.
      //  En effekt av dette er at man får lov å laste ned et sertifikat som innholder to tester når man har bestått bare en av dem.
    
    

    Comments, and variable names should be in English.
    The presence of a TODO comment makes me think the code is not complete; one of the requirements is that the code should be as much complete as it can.

  7.           $cert = new stdClass();
              $cert_node = node_load($data->nid);
              $cert->title = $cert_node->title;
              $cert->body = $cert_node->body;
              $cert->nid = $data->nid;
              $cert->certificate_template = $data->certificate_template;
              $cert->quizzes[] = $quiz;
              $cert->downloadable = TRUE;
              $certificates[$data->nid] = $cert;
    
    

    Is the code checking if the user has access to the node, before to show its data?

  8.       $output = filter_filter('process', 2, NULL, file_get_contents( dirname(__FILE__) . "/README.txt") );
    
    

    There is a Drupal function to get the name of the directory where a module is installed.

fuzzy76’s picture

Status: Needs work » Needs review
StatusFileSize
new577.33 KB

Thank you for doing this! I thought I was being very thorough, but obviously there were some gaps in the code. :)

Your remarks:

  1. I removed the check for the existence of the quiz module. But I still need to check for the version number, since anything below v4 won't work. It's not pretty, hopefully Drupal might implement versioning dependencies some lucky day. ;)
  2. I did read that document thoroughly. :( I think I followed the standard pretty well, but if there's anything particular you were reacting to, let me know. Edit: Oops. Renamed collect_certificates() to _certify_collect_certificates()...
  3. Fixed. Though I'm not 100% sure wether that default value will ever be used. Also fixed default value for certify_certificate_path.
  4. Moved to a separate function for re-use and changed to drupal_set_header().
  5. Fixed.
  6. Fixed. The code is complete as it is, it just have some limitations when it comes to different revisions of quizzes. :)
  7. It definitely lacks an access check (since that function might be called from several places). Fixed in two occurrences.

    There is also some loading of quiz data before that code which some might argue needs to be checked. For that one, I guess I am assuming that if a user has answered a quiz, it has to be viewable by the user. This might not necessarily be true, but has some weird implications. If a user passes a quiz and is issued a certificate, should the certificate be still be available if the users permission to see the quiz is revoked? I'm not 100% sure which way to go on that one.

  8. Fixed in several places.

Other:

  • BUGFIX: Preview certificate template did not work if certificate did not have a custom certificate set. Now sends the default certificate instead.

Hopefully I set the correct status for this "issue".

avpaderno’s picture

Status: Needs review » Fixed

Thank you for your contribution! I am going to update your account.

These are some recommended readings to help with excellent maintainership:

You can find more contributors chatting on the IRC #drupal-contribute channel. So, come hang out and stay involved.
Thank you, 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.

I thank all the dedicated reviewers as well.

Status: Fixed » Closed (fixed)
Issue tags: -Module review

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

avpaderno’s picture

Component: Miscellaneous » new project application
Assigned: Unassigned » avpaderno
Issue summary: View changes
avpaderno’s picture