napdf.class.php

Go to the documentation of this file.
00001 <?php
00002     /**
00003         \file napdf.class.php
00004         
00005         \brief This is the structural implementation of a PDF-printable list. It is meant to be a base for focused lists.
00006     */
00007 
00008     require_once ( dirname ( __FILE__ ).'/fpdf16/fpdf.php' );                           ///< This is the FPDF class, used to create the PDF.
00009     require_once ( dirname ( __FILE__ ).'/../standalone/BMLT_Satellite.class.php' );    ///< This is the class we use to communicate with the root server.
00010     
00011     /**
00012         \brief This class sets up a boilerplate FPDF instance to be used to generate the PDF.
00013         
00014         It is a SINGLETON pattern. This should be created in bunches, because the objects can be quite big, and the static elements
00015         make the key sorting easier.
00016     */
00017     class napdf extends FPDF
00018     {
00019         static $fpdf_instance = null;   ///< This is a SINGLETON, so we'll be using this as our instance.
00020         static $sort_order_keys = null; ///< This specifies which keys will be sorted. See the set_sort function for a description of how this works.
00021         static $week_starts = 1;        ///< We assume that the week starts on Sunday. 1 - Sunday, 7 - Saturday. Set this to whatever day the week starts.
00022         static $sort_callback = 'napdf::sort_meeting_data_callback';        ///< Used to sort the CSV data. It can be replaced with a call to a custom sorter.
00023         
00024         var $bmlt_instance = null;  ///< We manage an instance of the class used to extract CSV data from the root server.
00025         var $meeting_data = null;   ///< This will be an array, with the returned meeting data.
00026         var $format_data = null;    ///< This will be an array, with the returned format data.
00027         var $lang_search = array ( 'en' );  ///< Set this to the specific language[s], if we are looking for formats in a specific language. Default is 'en'.
00028         
00029         /**
00030             \brief Fetches the CSV data, and loads up our internal data array with all the meeting data. It creates an associative array
00031             of the meeting data.
00032             
00033             This loads the internal $meeting_data nested array, in which each meeting is one row, then an associative array of meeting data values.
00034         */
00035         private function FetchCSV ( $in_http_vars = null    ///< These contain alternatives to the $_GET and/or $_POST parameters. Default is null.
00036                         )
00037             {
00038             if ( $this->bmlt_instance instanceof BMLT_Satellite )
00039                 {
00040                 // First, we get the formats.
00041                 $format_data = $this->bmlt_instance->Execute ( 'csv_formats', array ( 'lang_enum' => $this->lang_search ) );
00042                 if ( $format_data )
00043                     {
00044                     $format_data_ar = explode ( "\n", $format_data );
00045                 
00046                     if ( is_array ( $format_data_ar ) && (count ( $format_data_ar ) > 1) )
00047                         {
00048                         $this->format_data = array();
00049                         
00050                         $keys = explode ( '","', $format_data_ar[0] );
00051                         
00052                         for ( $c = 0; $c < count ( $keys ); $c++ )
00053                             {
00054                             $keys[$c] = stripslashes ( preg_replace ( '/^\"|\"$/', '', $keys[$c] ) );
00055                             }
00056                         
00057                         $format_data_ar[0] = null;
00058                         unset ( $format_data_ar[0] );
00059                         
00060                         foreach ( $format_data_ar as $format )
00061                             {
00062                             $format = explode ( '","', $format );
00063                             if ( is_array ( $format ) && (count ( $format ) == count ( $keys )) )
00064                                 {
00065                                 $fmt = array ();
00066                                 $count = 0;
00067                                 foreach ( $keys as $key )
00068                                     {
00069                                     $fmt[$key] = stripslashes ( preg_replace ( '/^\"|\"$/', '', $format[$count++] ) );
00070                                     }
00071                                 
00072                                 $this->format_data[$fmt['id'].'_'.$fmt['lang']] = $fmt;
00073                                 }
00074                             }
00075                         }
00076                     }
00077                 // Next, we get the meetings.
00078                 $meeting_data = $this->bmlt_instance->Execute ( 'csv', $in_http_vars );
00079                 if ( $meeting_data )
00080                     {
00081                     $meeting_data_ar = explode ( "\n", $meeting_data );
00082                 
00083                     if ( is_array ( $meeting_data_ar ) && (count ( $meeting_data_ar ) > 1) )
00084                         {
00085                         $this->meeting_data = array();
00086                         
00087                         $keys = explode ( '","', $meeting_data_ar[0] );
00088                         
00089                         for ( $c = 0; $c < count ( $keys ); $c++ )
00090                             {
00091                             $keys[$c] = stripslashes ( preg_replace ( '/^\"|\"$/', '', $keys[$c] ) );
00092                             }
00093                         
00094                         $meeting_data_ar[0] = null;
00095                         unset ( $meeting_data_ar[0] );
00096                         
00097                         foreach ( $meeting_data_ar as $meeting )
00098                             {
00099                             $meeting = explode ( '","', $meeting );
00100                             if ( is_array ( $meeting ) && (count ( $meeting ) == count ( $keys )) )
00101                                 {
00102                                 $mtg = array ();
00103                                 $count = 0;
00104                                 foreach ( $keys as $key )
00105                                     {
00106                                     $mtg[$key] = stripslashes ( preg_replace ( '/^\"|\"$/', '', $meeting[$count++] ) );
00107                                     }
00108                                 
00109                                 array_push ( $this->meeting_data, $mtg );
00110                                 }
00111                             }
00112                         }
00113                     }
00114                 }
00115             else
00116                 {
00117                 throw new Exception ( 'No BMLT object!' );
00118                 }
00119             }
00120         
00121         /**
00122             \brief  This is the object factory function. It will return the new instance of the napdf class.
00123             
00124             NOTE: This ALWAYS destroys the original object, so you need to keep that in mind!
00125             
00126             \returns A reference to an instance of napdf
00127         */
00128         static function MakeNAPDF ( $in_x,                  ///< The width of each printed page, in $in_units
00129                                     $in_y,                  ///< The height of each printed page, in $in_units
00130                                     $in_http_vars,          ///< The various parameters used to dictate the meeting search.
00131                                     $in_units = 'in',       /**< The measurement units.
00132                                                                 - 'in' (Inches)
00133                                                                 - 'mm' (Millimeters)
00134                                                                 - 'cm' (Centimeters)
00135                                                                 - 'pt' (Points)
00136                                                                 Default is 'in'.
00137                                                             */
00138                                     $in_orientation = 'P',  /**< The orientation
00139                                                                 - 'P' (Portrait)
00140                                                                 - 'L' (Landscape)
00141                                                                 Default is 'P'
00142                                                             */
00143                                     $in_keys = null,        ///< Optional. If the sort keys are passed in here, we'll sort the data.
00144                                     $in_lang_search = null  ///< Optional. An array of language enums, used to extract the correct format codes.
00145                                     )
00146             {
00147             self::$fpdf_instance = null;
00148             self::$fpdf_instance = new napdf ( $in_x, $in_y, $in_http_vars, $in_units, $in_orientation, $in_lang_search );
00149             
00150             if ( self::$fpdf_instance instanceof napdf )
00151                 {
00152                 if ( (self::$fpdf_instance->bmlt_instance instanceof BMLT_Satellite) && is_array ( self::$fpdf_instance->meeting_data ) )
00153                     {
00154                     if ( is_array ( $in_keys ) )
00155                         {
00156                         self::$fpdf_instance->set_sort ( $in_keys );
00157                         }
00158                     }
00159                 else
00160                     {
00161                     self::$fpdf_instance = null;
00162                     }
00163                 }
00164             else
00165                 {
00166                 self::$fpdf_instance = null;
00167                 }
00168             
00169             return self::$fpdf_instance;
00170             }
00171         
00172         /**
00173             \brief  This is the way you sort the meeting data.
00174         */
00175         function set_sort ( $in_keys    /**<    This is the way we control a sort. It is both very powerful, and non-trivial.
00176                                                 This is an associative array, and the order of the keys determines sort priority,
00177                                                 with the first key being the highest priority, and subsequent keys descending in
00178                                                 importance.
00179                                                 
00180                                                 This sort is far more powerful than the basic one used in the root server. It is designed
00181                                                 to allow you to be very specific in your sort criteria for your printed list.
00182                                                 
00183                                                 The value of each key determines the direction of the sort. If it is 0, false or null,
00184                                                 the sort will be descending (lower to greater). If it is 1 or true, then the sort will
00185                                                 be ascending.
00186                                                 
00187                                                 This function executes the sort, so the meeting_data array is sorted after this function.
00188                                         */
00189                                 )
00190             {
00191                 if ( isset ( $in_keys['week_starts'] ) && ($in_keys['week_starts'] > 0) && ($in_keys['week_starts'] < 8) )  // This little dope fiend move is how we set a non-Sunday week start.
00192                     {
00193                     self::$week_starts = $in_keys['week_starts'];
00194                     }
00195                 
00196                 self::$sort_order_keys = $in_keys;
00197                 
00198                 return usort ( $this->meeting_data, self::$sort_callback );
00199             }
00200         
00201         /**
00202             \brief  This is a static callback function to be used for sorting the multi-dimensional meeting_data
00203                     array. It uses the sort_order_keys array to determine the sort.
00204                     
00205             \returns an integer. -1 if a < b, 0 if a == b, or 1 if a > b.
00206         */
00207         static function sort_meeting_data_callback (    &$in_a,     ///< The first meeting array to compare
00208                                                         &$in_b      ///< The second meeting array to compare
00209                                                         )
00210             {
00211             $ret = 0;
00212             
00213             if ( is_array ( $in_a ) && is_array ( $in_b ) && is_array ( napdf::$sort_order_keys ) )
00214                 {
00215                 // We reverse the array, in order to sort from least important to most important.
00216                 $sort_keys = array_reverse ( napdf::$sort_order_keys, true );
00217                 
00218                 foreach ( $sort_keys as $key => $value )
00219                     {
00220                     if ( isset ( $in_a[$key] ) && isset ( $in_b[$key] ) )
00221                         {
00222                         $val_a = trim ( $in_a[$key] );
00223                         $val_b = trim ( $in_b[$key] );
00224 
00225                         if ( ('weekday_tinyint' == $key) && (napdf::$week_starts > 1) && (napdf::$week_starts < 8) )
00226                             {
00227                             $val_a -= napdf::$week_starts;
00228 
00229                             if ( $val_a < 0 )
00230                                 {
00231                                 $val_a += 8;
00232                                 }
00233                             else
00234                                 {
00235                                 $val_a += 1;
00236                                 }
00237                             
00238                             $val_b -= napdf::$week_starts;
00239                             
00240                             if ( $val_b < 0 )
00241                                 {
00242                                 $val_b += 8;
00243                                 }
00244                             else
00245                                 {
00246                                 $val_b += 1;
00247                                 }
00248                             }
00249 
00250                         // We know a few keys already, and we can determine how the sorting goes from there.
00251                         switch ( $key )
00252                             {
00253                             case 'start_time':
00254                             case 'duration_time':
00255                                 $val_a = strtotime ( $val_a );
00256                                 $val_b = strtotime ( $val_b );
00257                             case 'weekday_tinyint':
00258                             case 'id_bigint':
00259                             case 'shared_group_id_bigint':
00260                             case 'service_body_bigint':
00261                                 $val_a = intval ( $val_a );
00262                                 $val_b = intval ( $val_b );
00263                             case 'longitude':
00264                             case 'latitude':
00265                                 if ( $val_a > $val_b )
00266                                     {
00267                                     $ret = 1;
00268                                     }
00269                                 elseif ( $val_b > $val_a )
00270                                     {
00271                                     $ret = -1;
00272                                     }
00273                             break;
00274                             
00275                             default:
00276                                 // We ignore blank values
00277                                 if ( strlen ( $val_a ) && strlen ( $val_b ) )
00278                                     {
00279                                     $tmp = strcmp ( strtolower ( $val_a ), strtolower ( $val_b ) );
00280                                     
00281                                     if ( $tmp != 0 )
00282                                         {
00283                                         $ret = $tmp;
00284                                         }
00285                                     }
00286                             break;
00287                             }
00288                         }
00289                     
00290                     if ( !$value )
00291                         {
00292                         $ret = -$ret;
00293                         }
00294                     }
00295                 }
00296             
00297             return $ret;
00298             }
00299         
00300         /**
00301             \brief  The class constructor. Sets up the instance, and reads in the meeting data.
00302             
00303             It's private, in order to keep multiple instances from being created. Use MakeNAPDF() to create objects.
00304         */
00305         private function __construct (  $in_x,                  ///< The width of each printed page, in $in_units
00306                                         $in_y,                  ///< The height of each printed page, in $in_units
00307                                         $in_http_vars,          ///< The various parameters used to dictate the meeting search.
00308                                         $in_units = 'in',       /**< The measurement units.
00309                                                                     - 'in' (Inches)
00310                                                                     - 'mm' (Millimeters)
00311                                                                     - 'cm' (Centimeters)
00312                                                                     - 'pt' (Points)
00313                                                                     Default is 'in'.
00314                                                                 */
00315                                         $in_orientation = 'P',  /**< The orientation
00316                                                                     - 'P' (Portrait)
00317                                                                     - 'L' (Landscape)
00318                                                                     Default is 'P'
00319                                                                 */
00320                                         $in_lang_search = null  ///< An array of language enums, used to extract the correct format codes.
00321                                         )
00322             {
00323             if ( is_array ( $in_lang_search ) && count ( $in_lang_search ) )
00324                 {
00325                 $this->lang_search = $in_lang_search;
00326                 }
00327             /* We use the static function to create the SINGLETON. */
00328             $this->bmlt_instance = BMLT_Satellite::MakeBMLT ( true );   // Make a special CSV object.
00329             
00330             /* Quick sanity check. */
00331             if ( !($this->bmlt_instance instanceof BMLT_Satellite) )
00332                 {
00333                 throw new Exception ( 'The BMLT object could not be created' );
00334                 }
00335             $this->FPDF ( $in_orientation, $in_units, array ( $in_x, $in_y ) );
00336             $this->SetAutoPageBreak ( 0 );
00337             $this->SetAuthor ( "BMLT" );
00338             $this->SetCreator ( "BMLT" );
00339             $this->SetSubject ( "Printable Meeting List" );
00340             $this->SetTitle ( "Printable Meeting List" );
00341             $this->FetchCSV ( $in_http_vars );
00342             // Okay, at this point, we've set up the PDF object, and have done the meeting search. Our meetings are waiting for us to start making the list.
00343             }
00344     };
00345 ?>
 All Data Structures Files Functions Variables Enumerations